【发布时间】:2016-05-03 17:12:14
【问题描述】:
看起来静态方法与静态Func字段相同。我错过了什么,还是它们本质上可以互换(相同的足迹等)?
静态属性最终与其他两个示例相同,只是它包含“get”访问器的(最小)开销。
也许问起来有点毫无意义和直视肚脐……但我喜欢了解“幕后”发生的事情,即使它并不立即相关。
可以肯定的是:我不打算将所有静态方法都转换为 lambda 表达式(这会让我的同事发疯)。但是,在某些合理的情况下,静态变量比编写方法更有意义。或者可能相反:说服某人使用静态方法而不是 lambda 表达式来使代码更具可读性或其他什么
另外,我很好奇是否有更好的方法来调查这类问题
我的测试
我把这个简单的例子放到 LINQPad 中(v4.57.02,“compile with /optimize+”启用):
void Main()
{
var hold = "this is the thing. it returns true";
var held = "this is the one that returns false";
Console.WriteLine(One.Check(hold));
Console.WriteLine(One.Check(held));
Console.WriteLine(Two.Check(hold));
Console.WriteLine(Two.Check(held));
}
// Define other methods and classes here
class One
{
public static bool Check(string value)
{
return value != null && value.Contains('.');
}
}
class Two
{
public static Func<string, bool> Check = v => v != null && v.Contains('.');
}
... 它为两者生成了相同的 IL。本质上:
XXX.Check:
IL_0000: ldarg.0
IL_0001: brfalse.s IL_000C
IL_0003: ldarg.0
IL_0004: ldc.i4.s 2E
IL_0006: call System.Linq.Enumerable.Contains
IL_000B: ret
IL_000C: ldc.i4.0
IL_000D: ret
XXX..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: ret
【问题讨论】:
-
你的字段不是
readonly,所以我可以Two.Check = string.IsNullOrEmpty;。 -
@JeppeStigNielsen 我错过了“= v”部分……需要更多咖啡。
-
@JeppeStigNielsen 好点。不确定这是一个特性还是一个错误:) 在实践中,我确信有人会用一个属性来包装它(嗯……“在实践中”我会使用一种方法,但你知道)
-
你可以做
Two.Check.GetInvocationList();和Console.WriteLine(Two.Check);等等。另一个可以参与方法组转换,如Predicate<string> variable = One.Check;。
标签: c# methods lambda static static-methods