Создание экземпляра делегата C# по сравнению с простой передачей ссылки на метод

У меня простой вопрос: в чем преимущество создания экземпляра делегата C# по сравнению с простой передачей ссылки на функцию? Я имею в виду:

Почему:

Thread t = new Thread(new ThreadStart(SomeObject.SomeMethod));

Когда можно сделать:

Thread t = new Thread(SomeObject.SomeMethod);

Оба будут компилироваться и работать в моем опыте... я что-то упустил?


person Jrop    schedule 02.02.2010    source источник
comment
возможный дубликат В чем разница между new Action() и лямбда?   -  person nawfal    schedule 07.07.2014


Ответы (3)


Пока группа методов SomeObject.SomeMethod имеет метод с типом возвращаемого значения void и не принимает никаких параметров, нет никакой разницы. Это связано с тем, что ThreadStart определяется как delegate, который возвращает void и не принимает никаких параметров, и поэтому существует неявное преобразование из группы методов SomeObject.SomeMethod в ThreadStart. Таким образом, оба вызывают перегрузку Thread(ThreadStart) конструктора Thread .

Соответствующим разделом спецификации языка является §6.6 (Преобразование группы методов).

У меня простой вопрос: в чем преимущество создания экземпляра делегата C# по сравнению с простой передачей ссылки на функцию?

Так что тут просто поправочка в терминологии. С участием

class MyObject {
    public void SomeMethod() { }
}

MyObject someObject = new MyObject();

вещь, обозначенная someObject.SomeMethod, является группой методов. Вы можете просто думать об этом как о наборе перегруженных методов, которые можно искать, используя нотацию someObject.SomeMethod.

person jason    schedule 02.02.2010
comment
Является ли someObject.SomeMethod() также группой методов? - person John Feminella; 02.02.2010
comment
@John Feminella: Нет, это будет вызов метода. - person jason; 02.02.2010
comment
Хм, хорошо. Что если у SomeMethod было несколько перегрузок, сигнатура которых соответствовала SomeMethod(...), где ... — произвольные параметры? Является ли это группой методов, поскольку она может ссылаться на один из нескольких методов и еще не разрешена? - person John Feminella; 02.02.2010
comment
@John Feminella: извините, ваш вопрос мне не ясен. Вы спрашиваете о выражении вызова. Например, someObject.SomeMethod(parameter1, parameter2, ..., parametern), где каждое из parameterj является выражением, ref variable reference или out variable reference? Для такого выражения либо существует наилучшая применимая перегрузка (§7.4.3 спецификации), либо делается попытка обработать выражение как вызов метода расширения, либо возникает ошибка времени компиляции; чтобы было ясно: неоднозначные вызовы являются ошибками времени компиляции. Это то, о чем вы спрашиваете? - person jason; 02.02.2010
comment
Возможно, я неправильно понимаю, что такое группа методов. Я исхожу из вашего последнего предложения, в котором говорится, что это набор перегруженных методов, которые можно найти с помощью нотации .... Если я напишу SomeMethod(a, b) и есть несколько перегрузок, которые могут соответствовать этим аргументам (даже если один в конечном итоге разрешается быть правильным через правила разрешения перегрузки), это группа методов? - person John Feminella; 02.02.2010
comment
@John Feminella: Нет, это не группа методов, это вызов метода. Обратите внимание, что в моем предложении, на которое вы ссылаетесь, нет скобок и т. д. в выражении someObject.SomeMethod. Как только круглые скобки и параметры добавляются в выражение, оно либо становится допустимым выражением вызова, либо возникает ошибка времени компиляции. - person jason; 02.02.2010

Компилятор сделает вывод, что когда вы вводили более короткий код, вы имели в виду более длинный код. Нет никакой разницы в конечном эффекте. Если вам нужна ясность полного конструктора, вы можете добавить его; если вам нужна краткость только группы методов, вы можете позволить компилятору вывести конструктор. Это просто стилистический выбор.

person Eric Lippert    schedule 02.02.2010

Это эквивалентно. Хорошая вводная статья по теме: Делегаты C#, анонимные методы и лямбда-выражения — O My!

person herzmeister    schedule 02.02.2010