什么是两者之间的区别?
Class1.Method1<Guid, BECustomer>("cId", Facade.Customers.GetSingle);
并且Class1.Method1<Guid, BECustomer>("cId", x => Facade.Customers.GetSingle(x));
Resharper建议使用第一个表达式。
什么是两者之间的区别?
Class1.Method1<Guid, BECustomer>("cId", Facade.Customers.GetSingle);
并且Class1.Method1<Guid, BECustomer>("cId", x => Facade.Customers.GetSingle(x));
Resharper建议使用第一个表达式。
就结果而言,两者没有区别。但是第二种方式会创建一个额外的重定向:代码首先会调用一个以一个名为x
的参数命名的匿名方法,然后该方法再使用该参数调用Facade.Customers.GetSingle
。这个重定向完全没有好处,这就是为什么ReSharper建议您使用第一种选择。
Facade.Customers
会随时间变化而改变。那么第一个(来自命名方法的方法组)将保留原始Customers
,而第二个(来自Lambda表达式的匿名函数)将反映新的Customers
(Customers
由匿名函数重新计算)。因此,在第二个中,评估是“延迟”的。如果这很难理解,请尝试运行此代码:string test = "12345"; Func<string, bool> f = test.Contains; Func<string, bool> g = x => test.Contains(x); test = "changed!"; bool a = f("34"); bool b = g("34");
。 - Jeppe Stig Nielsenref
参数的示例。也就是说,代码static void M1(ref string s) { Func<string, bool> f1 = s.Contains; /* OK */ }
是可以的;但是代码static void M2(ref string s) { Func<string, bool> f2 = x => s.Contains(x); /* Compile-time error, cannot close over 'ref' parameter */ }
是不合法的。 - Jeppe Stig Nielsen在幕后,如果您使用lambda表达式,编译器将生成更多的代码。但是对于方法组,它只创建一个指向该方法的新委托:
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>)
使用Lambda表达式,将在类上创建一个匿名方法(<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>
参数时,Func<Guid, BECustomer>
是与以下同义词:
public delegate BECustomer Func(Guid arg);
Func
都只是一个通用的委托:public delegate TResult Func<T, TResult>(T arg);
Func<Guid, BECustomer>
与 Facade.Customers.GetSingle
的方法组兼容,因为方法签名与委托签名匹配。