Func <T> () проти Func <T> .Invoke ()


83

Мені цікаво про різницю між прямим викликом Func та використанням Invoke () на ньому. Чи є різниця? Чи є перший, синтаксичний цукор і виклики Invoke () внизу?

public T DoWork<T>(Func<T> method)
{
    return (T)method.Invoke();
}

проти

public T DoWork<T>(Func<T> method)
{
    return (T)method();
}

Або я зовсім на неправильному шляху :) Дякую.


Відповіді:


113

Різниці немає взагалі. Другий - це просто скорочення Invoke, надане компілятором. Вони складаються в один і той же ІЛ.


1
Якщо метод Invoke () вимкнено, це призводить до помилки компілятора: "Не вдається неявно перетворити тип 'System.Func <T>' на 'T'". Я компілюю проти .NET 4.
Майк,

2
@Mike: Це могло б статися, якби ви також пропустили дужки - тобто спробували повернутись, (T)methodа не (T)method().
Джон Скіт

@JonSkeet Так цей хлопець неправильно тут: social.msdn.microsoft.com/Forums/en-US / ...
superlogical

4
@superlogical: Тут є дві проблеми. По-перше, питання полягає в різниці між викликом методу безпосередньо та викликом його через делегат. Це не те саме, що різниця між foo()і foo.Invoke()де fooє змінною типу делегата. Інша проблема полягає в тому, що у відповіді, схоже, йдеться про те Control.Invoke, що не те саме, що закликати Invokeделегата.
Джон Скіт,

2
@LucaCremonesi: Якщо це результат виклику методу, мені загалом подобається Invoke, як це GetAction()()виглядає дивно, але GetAction().Invoke()виглядає нормально. Але я не проти ні в якому разі, здебільшого.
Джон Скіт,

17

Invoke добре працює з новим оператором розповсюдження нуля C # 6, тепер ви можете це зробити

T result = method?.Invoke();

замість

T result = method != null ? method() : null;

Чи можете ви проілюструвати сценарій, коли це корисно? Справа підручника викликає події.
Гусдор,

1
Наприклад, у вас може бути необов'язковий параметр Func, який, якщо не присвоєно жодне значення, є типовим (Func), який є нульовим і ігнорується.
Остін Сальгат,

1
Це звичайний випадок для подій та інших делегатів із кількома складаннями - вони зазвичай ініціалізуються значенням null і отримують ненульове значення після виклику +=. Тож якщо ви збираєтеся запустити подію і не знаєте, чи є якісь підписки, стислим рішенням є дзвінок ?.Invoke(...).
стоп-
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.