我想用更优雅的结构

时间:2014-09-23 18:02:44

标签: c#

我不是C#的高年级学生,所以我应该学习更多基础知识,但这是我的代码:

var out1 = obj1.F1();
var out2 = obj2.F2(out1);
var out3 = obj3.F3(out2);
var out4 = obj4.F4(out3);

其他方式是在一行中做同样的事情:

var out4 = obj4.F4( obj3.F3( obj2.F2( obj1.F1()  ) ) );

但是,更难以阅读,更层次化,提醒xml标签

所以我想让它更具功能性。它应该看起来像'管道','传送带',其中一个功能输入其他功能。我的解决方案(拐杖):

var obj = new[]{0}; //first looking bad thing, without that you are operating with each element of F1() result
var something = obj
       .Select(x => obj1.F1() ) //second: x=>  x doesn't take part in right side
       .Select(x => obj2.F2(x) )
       .Select(x => obj3.F3(x) )
       .Select(x => obj4.F4(x) )
       .ToArray(); //third: without that it doesn't do anything

你应该如何编码这种'模式'?

3 个答案:

答案 0 :(得分:1)

您可以简单地创建一个对单个项目执行相同操作的运算符,而不是尝试使用专为序列设计的Enumerable.Select(<1}}:

public static TResult Map<TSource, TResult>(
    this TSource source, Func<TSource, TResult> selector)
{
    return selector(source);
}

然后你可以使用它而不需要对序列进行笨拙的转换:

var result = obj1.F1()
    .Map(x => obj2.F2(x))
    .Map(x => obj3.F3(x))
    .Map(x => obj4.F4(x));

答案 1 :(得分:1)

你可以这样做:

var result = obj1.F1().Pipe(obj2.F2).Pipe(obj3.F3).Pipe(obj4.F4);

(使用以下扩展方法)

static class Extensions
{
    public static TOut Pipe<TIn, TOut>(this TIn input, Func<TIn, TOut> func)
    {
        return func(input);
    }
}

不确定它真的更具可读性,但是......

答案 2 :(得分:0)

嗯,你的例子有点差,因为我不知道这些方法到底在做什么。它们没有任何可以推断其目的的名称,因此我们无法就如何继续提供很多建议。

例如,假设这是一个图像处理库,你正在做类似的事情:

(这是伪代码)

var img = new Image();
var trimmedImage = TrimWhitespace(img);
var rotatedImage = RotateImage(trimmedImage);
var zoomedImage = ZoomImage(rotatedImage);

我仍然永远不会链接它们,但如果我需要以表示层格式重复使用它,我会设置一个协调它的对象,即:

var formattedImage = ImageFormatter.Format(new Image());

和ImageFormatter将按照伪代码中概述的顺序调用它们。