6

我不知道如何更好地描述它,所以标题可能有点混乱。

我想知道是否可以通过使用实例化一个类,... = new MyClass()并在实例化时立即调用该类的非静态方法?

例如这样的:

return new MyClass().SetName("some name");

我想我以前见过类似的东西,但我找不到。做类似的事情有点烦人......

MyClass myclass = new MyClass();
myclass.SetName("some name");
return myclass;

有没有办法缩短它或像我的第一个例子那样做?(请不要建议我使用属性来代替SetName(string)- 这只是一个例子)

提前致谢!

4

7 回答 7

19

好吧,如果你确实有一个属性,你可以使用一个对象初始化器:

return new MyClass { Name = "some name" };

如果你真的,真的必须使用一个方法,那么唯一的选择是让方法再次返回实例:

public Foo SomeMethod()
{
    // Do some work
    return this;
}

你可以这样写:

return new Foo().SomeMethod();

如果你不能改变你正在调用的方法,作为一种非常极端的做事方式,你可以编写一个扩展方法:

public static T ExecuteAndReturn<T>(this T target, Action<T> action)
{
    action(target);
    return target;
}

然后你可以写:

return new Foo().ExecuteAndReturn(f => f.SomeMethod());

但这真的很犯规。在这些情况下使用局部变量会简单得多......

于 2013-03-01T14:49:19.207 回答
7

如果SetName返回this,那么您可以完全按照您在第一个代码示例中想要执行的操作。

于 2013-03-01T14:48:41.507 回答
7

这个问题有一个很大的误解

...并在实例化时立即调用此类的非静态方法

例如这样的:

return new MyClass().SetName("some name");

事实上,调用SetName函数是在实例化完成之后发生的。它不会在“实例化时”发生。这与以下内容完全相同:

MyClass newInstance new MyClass();
return newInstance.setName("some name");

所以当SetName方法被调用时,构造函数已经完成了它需要做的所有事情,对象在堆上已经准备好了。

除此之外,它在语法上是可行的,您只需要this按照其他人的说明返回,当然还需要相应地指定返回类型。但是,我不会为二传手这样做……这可不好。

此外,如果您总是必须设置名称,请考虑使用期望名称作为参数的构造函数,并将其设置在构造函数中:

public class MyClass
{
    public String name;
    public MyClass(String initialName)
    {
        name = initialName;
    }
}

然后您可以以非常简短的形式使用它:

MyClass instance = new MyClass("someName");
于 2013-03-01T14:52:31.840 回答
6

这很容易做到。通常这被称为“流利的接口”,但具有更合适的方法名称。

以下是您将如何编写 SetName 来实现这样的功能:

public MyClass SetName(...)
{
    ...
    return this;
}

这将允许您准确地使用您想要的语法。

然后,您可以链接多个此类调用,通常链接到不同的方法:

return new MyClass().SetName("kkk").SetAge(44).SetAddres("...");

但是,我建议您还考虑添加一个更合适的构造来完成所有这些操作。

于 2013-03-01T14:49:01.067 回答
3

您可以像这样使方法可链接:

public void SetName(String name) {
    this._name = name;
    return this;
}
于 2013-03-01T14:48:58.890 回答
3

除非SetName是托管它并返回的类的类型,否则this您无法避免中间变量。当然,您可以采用流利的语法,并让您SetName返回对象,但这不是 C# 的原生习惯用法。

class MyClass {
    public int A {get;private set;}
    public int B {get;private set;}
    public MyClass SetA(int a) {
        A = a;
        return this;
    }
    public MyClass SetB(int b) {
        B = b;
        return this;
    }
}

现在你可以这样做:

return new MyClass().SetA(123).SetB(456);
于 2013-03-01T14:49:21.457 回答
1

您可以创建一个静态属性作为工厂,返回一个新实例。在这种情况下,调用将如下所示:

MyClass.GetInstance.SetName("some name");

不确定这是否是您想要的。或者,为什么不从构造函数中调用该方法并通过构造函数传递所需的参数。

或者,第三种选择,构建一个工厂类来处理所有这些额外的步骤并返回给你一个实例。

于 2013-03-01T14:50:10.097 回答