C#:为方法嵌套返回'this'?

Svi*_*ish 14 c# methods fluent-interface return-value

我有一个班级,我必须多次互相称呼一两种方法.目前返回的方法void.我在想,让它返回会更好this,这样方法可以嵌套吗?或者这是非常非常非常糟糕的?或者,如果它返回一个相同类型的新对象会更好吗?或者您怎么看?作为一个例子,我创建了三个版本的加法器类:

// Regular
class Adder
{
    public Adder() { Number = 0; }

    public int Number { get; private set; }

    public void Add(int i) { Number += i; }
    public void Remove(int i) { Number -= i; }
}

// Returning this
class Adder
{
    public Adder() { Number = 0; }

    public int Number { get; private set; }

    public Adder Add(int i) { Number += i; return this; }
    public Adder Remove(int i) { Number -= i; return this; }
}

// Returning new
class Adder
{
    public Adder() : this(0) { }
    private Adder(int i) { Number = i; }

    public int Number { get; private set; }

    public Adder Add(int i) { return new Adder(Number + i); }
    public Adder Remove(int i) { return new Adder(Number - i); }
}
Run Code Online (Sandbox Code Playgroud)

第一个可以这样使用:

    var a = new Adder();
    a.Add(4);
    a.Remove(1);
    a.Add(7);
    a.Remove(3);
Run Code Online (Sandbox Code Playgroud)

另外两个可以这样使用:

    var a = new Adder()
        .Add(4)
        .Remove(1)
        .Add(7)
        .Remove(3);
Run Code Online (Sandbox Code Playgroud)

唯一的区别在于,a在第一种情况下new Adder(),后者中的while是最后一种方法的结果.

第一个我发现很快就会变得......一遍又一遍地写作很烦人.所以我想使用其他版本之一.

第三种方法与许多其他方法类似,例如许多String方法和IEnumerable扩展方法.我想这有一个积极的一面,你可以做一些事情var a = new Adder(); var b = a.Add(5);,然后有一个是0和一个是5.但同时,创建新对象是不是有点昂贵?什么时候第一个物体会死?当第一种方法返回时?要么?

无论如何,我喜欢那个回来this并认为我会用它的人,但我很好奇知道其他人对这个案子的看法.什么是最佳实践.

Bri*_*ian 19

'return this'风格有时被称为流畅的界面,是一种常见的做法.

  • 请注意,Fluent样式的写法类似于一个非常不同的替代方法,即使对象不可变并返回对象的新实例而不是修改内部状态.使用类似示例中的简单类(不是示例非常逼真),您可能需要考虑简单地使其变为不可变的优点和缺点. (2认同)
  • `return this`和`return new`都是不同应用程序的例子:jQuery` $('#eleId').show()`返回`this`,否则会创建eleId的副本.Linq`myCollection.Where(x => x.IsValid)`返回一个新对象,否则它会改变myCollection,这可能是不可变的. (2认同)

Ste*_*ger 6

我喜欢"流利的语法",并将采取第二个.毕竟,对于那些对流利语法感到不舒服的人,你仍然可以将它作为第一个使用.

另一个想法是使一个像加法器这样的界面更容易使用:

public Adder Add(params int[] i) { /* ... */ }
public Adder Remove(params int[] i) { /* ... */ }

Adder adder = new Adder()
  .Add(1, 2, 3)
  .Remove(3, 4);
Run Code Online (Sandbox Code Playgroud)

我总是尝试制作简短易读的界面,但很多人喜欢编写尽可能复杂的代码.