我最近创建了这个扩展方法:
public static TR Calculate<TS, TR>(this TS item, Func<TS, TR> selector)
=> selector(item);
Run Code Online (Sandbox Code Playgroud)
然后,我能够重构这个丑陋的代码,来自:
int value = panel.Controls.Cast<Control>().Last().Location.Y
+ panel.Controls.Cast<Control>().Last().Size.Height;
Run Code Online (Sandbox Code Playgroud)
至:
int value = panel.Controls.Cast<Control>().Last().Calculate(
o => o.Location.Y + o.Size.Height);
Run Code Online (Sandbox Code Playgroud)
我想知道是否有办法使用内置的.NET函数来实现这一点?
通过"先天",我猜你的意思是你自己不想要任何新方法?
好吧,你可以这样做:
value = ((Func<InputType, OutputType>)(o => o.First + o.Second + o.Property.Value))(collection[calc(param)]);
Run Code Online (Sandbox Code Playgroud)
基本上,将lambda转换为委托类型然后调用委托.
或者我可能过于复杂了.你实际想要的东西可能只是不写collection[calc(param)]那么多次.如果是这样的话,你可以:
var o = collection[calc(param)];
value = o.First + o.Second + o.Property.Value;
Run Code Online (Sandbox Code Playgroud)
我不明白为什么你不能这样做.
我真的建议你为这种转换编写一个单独的方法.它会更具可读性.
// name this properly so that it describes what you actually want.
public OutputType TransformCollectionItem(TInput o) {
return o.First + o.Second + o.Property.Value;
}
Run Code Online (Sandbox Code Playgroud)
我要说你不应该这样做 - 我认为这不会让代码更具可读性.
鉴于原始代码:
int value = panel.Controls.Cast<Control>().Last().Location.Y
+ panel.Controls.Cast<Control>().Last().Size.Height;
Run Code Online (Sandbox Code Playgroud)
您的扩展方法可以让您这样做:
int value = panel.Controls.Cast<Control>().Last().Calculate(
o => o.Location.Y + o.Size.Height);
Run Code Online (Sandbox Code Playgroud)
但是这样做似乎没有什么优势:
var c = panel.Controls.Cast<Control>().Last();
int value = c.Location.Y + c.Size.Height;
Run Code Online (Sandbox Code Playgroud)
后者实际上更短,并且不需要读者知道扩展方法.
此外,您的扩展方法将显示在一切的工具提示中...
请注意,它确实允许一些有趣的代码,如
double negated = 1.0.Calculate(x => -x);
Run Code Online (Sandbox Code Playgroud)