Мы начали с SendAsync, который принимает для отправки массив аргументов:
public void SendAsync(string method, object[] args);
Clients.All.SendAsync("Method", new object[] { arg1, arg2, arg3 });
Очевидно, что создавать массив каждый раз - это боль. Легко исправить это, используя параметры:
public void SendAsync(string method, params object[] args);
Clients.All.SendAsync("Method", arg1, arg2, arg3);
Однако это разваливается, когда вы действительно хотите отправить массив как один аргумент.
public void SendAsync(string method, params object[] args);
var arg1 = new object[] { a, b, c };
Clients.All.SendAsync("Method", arg1);
// C# 'params' expands this into the below
Clients.All.SendAsync("Method", a, b, c);
Поэтому вместо отправки одного аргумента, представляющего собой массив a, b, c, мы отправили каждый из них как отдельные аргументы. Это сбивало пользователей с толку.
Поэтому мы удалили из него параметры и вместо этого создаем целую кучу методов расширения, которые поддерживают несколько аргументов:
public void SendAsync(string method, object[] args);
public void SendAsync(string method, object arg1) => SendAsync(method, new object[] { arg1 });
public void SendAsync(string method, object arg1, object arg2) => SendAsync(method, new object[] { arg1, arg2 });
// ... etc ...
Но когда у вас есть такой код, все равно остается двусмысленность:
public void SendAsync(string method, object[] args);
public void SendAsync(string method, object arg1) => SendAsync(method, new object[] { arg1 });
var arg = new object[] { a, b, c }
Clients.All.SendAsync("method", arg);
Опять же, будет выбрана перегрузка, которая принимает объект [] (см. Эту иллюстрацию в SharpLab).
Итак, мы переименовали тот, который принимает массив, в SendCoreAsync:
public void SendCoreAsync(string method, object[] args);
public void SendAsync(string method, object arg1) => SendCoreAsync(method, new object[] { arg1 });
var arg = new object[] { a, b, c }
// No ambiguity here!
Clients.All.SendAsync("method", arg);