在.Net中链接方法的正确方法是什么

时间:2011-07-14 01:30:00

标签: .net extension-methods method-chaining

在.Net中,您可以链接返回值的方法或使用void。其中一个是“正确的方式”吗?

所以你可以说

1)

Foo myFoo = new Foo();
myfoo.Bars = 
  myBars.DoSomethingCool(x)
  .DoSomethingElse(y)
  .AndSomethingElse(z);

public static IList<IBar> DoSomethingCool(this IList<IBar> source, object x)
{
  IList<IBar> result = //some fn(source)
  return result;
}

在这种情况下,所有3种扩展方法都需要返回IList(myFoo.Bars的类型)

或者它也可以写成

2)

myBars.DoSomethingCool(x)
.DoSomethingElse(y)
.AndSomethingElse(z);

public static void DoSomethingCool(this IList<IBar> source, object x)
{
  //Modify source
  source = //some fn(source)
  //Don't return anything
}

在这种情况下,扩展方法返回一个void,但是对即将进入的源对象进行处理吗?

更新 Simon的回答是正确的2)无法编译。以下是如何重写的:

DoSomethingCool(myBars)
.DoSomethingElse(myBars)
.AndSomethingElse(myBars);

然后myBars会在每个方法的调用内部进行更改,并且方法将返回void。

2 个答案:

答案 0 :(得分:0)

在这两种情况下,您都在使用扩展方法,返回一个对象,然后使用该对象作为链中下一个方法的输入。第二个例子接近Fluent Interface(但不完全)。我认为在你的两个例子中,关键区别在于可变性。您是否希望修改原始输入(第二个示例)或不修改(第一个示例)? “正确”答案取决于具体情况和背景。

答案 1 :(得分:0)

1)胜利。西蒙正确地回答说2)不会编译,但他这样做是为了评论,所以我不能因为回答而得到他的信任。 2)的更新解决方案将所有内容都视为副作用,我无法想到为什么您希望以静态类型语言执行此操作。

关于链接调试问题的观点需要考虑,但我发现链接在过滤时特别有用。

mybars.FilterByHasHappyHour()

好得多
BigGiantUtilityClass.GetBarsWithHappyHours(myBars)