IEnumerable.Select()表示单个项目

Max*_*rda 0 c#

我最近创建了这个扩展方法:

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函数来实现这一点?

Swe*_*per 5

通过"先天",我猜你的意思是你自己不想要任何新方法?

好吧,你可以这样做:

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)

  • @MaximeR.甚至不要为此制作一个`SingleSelect`.只需创建一个专门用于转换数据的方法. (2认同)

Mat*_*son 5

我要说你不应该这样做 - 我认为这不会让代码更具可读性.

鉴于原始代码:

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)