Разница между лямбда-выражением и группой методов
в чем разница между
Class1.Method1<Guid, BECustomer>("cId", Facade.Customers.GetSingle);
и
Class1.Method1<Guid, BECustomer>("cId", x => Facade.Customers.GetSingle(x));
?
Resharper предлагает использовать первое выражение.
3 ответов
нет никакой разницы в отношении к результату. Однако второй создает дополнительное перенаправление: код сначала вызовет ваш анонимный метод, который принимает один параметр с именем x
а тот в свою очередь называет Facade.Customers.GetSingle
С этого параметра. Это перенаправление не имеет никакой пользы, поэтому ReSharper говорит вам использовать первую альтернативу.
за кулисами, компилятор генерирует намного больше кода, если вы используете лямбда-выражение. С группой методов он просто делает новый делегат, указывающий на этот метод:
L_0001: ldstr "cId"
L_0006: ldnull
L_0007: ldftn void Facade/Customers::GetSingle(valuetype [mscorlib]System.Guid)
L_000d: newobj instance void [mscorlib]System.Action`1<valuetype [mscorlib]System.Guid>::.ctor(object, native int)
L_0012: call void Class1::Method1<valuetype [mscorlib]System.Guid, class BECustomer>(string, class [mscorlib]System.Action`1<!!0>)
С лямбда-выражением в классе создается анонимный метод (<Test>b__0
на L_0025) и делегат ссылается на то, что вместо этого:
L_0018: ldstr "cId"
L_001d: ldsfld class [mscorlib]System.Action`1<valuetype [mscorlib]System.Guid> Class1::CS$<>9__CachedAnonymousMethodDelegate1
L_0022: brtrue.s L_0037
L_0024: ldnull
L_0025: ldftn void Class1::<Test>b__0(valuetype [mscorlib]System.Guid)
L_002b: newobj instance void [mscorlib]System.Action`1<valuetype [mscorlib]System.Guid>::.ctor(object, native int)
L_0030: stsfld class [mscorlib]System.Action`1<valuetype [mscorlib]System.Guid> Class1::CS$<>9__CachedAnonymousMethodDelegate1
L_0035: br.s L_0037
L_0037: ldsfld class [mscorlib]System.Action`1<valuetype [mscorlib]System.Guid> Class1::CS$<>9__CachedAnonymousMethodDelegate1
L_003c: call void Class1::Method1<valuetype [mscorlib]System.Guid, class BECustomer>(string, class [mscorlib]System.Action`1<!!0>)
где ваш Method1<Guid, BECustomer>
принимает , Func<Guid, BECustomer>
- это синоним:
public delegate BECustomer Func(Guid arg);
на самом деле, все a Func
is является общим делегатом:
public delegate TResult Func<T, TResult>(T arg);
компилятор может проанализировать код и определить, что ваш Func<Guid, BECustomer>
совместим с группой методов для Facade.Customers.GetSingle
потому что сигнатура метода соответствует подписи делегата.
это синтаксический сахар и еще один пример компилятора, выполняющего для вас работу grunt.