2

我在基类中有一个方法,它应该将类型的 self 实例作为派生类型返回。例如:

class A
{
   public string X { get; set; }

   public A SetX(string x)
   {
       this.X = x;
       return this;
   }
}

class B:A
{
   public string Y { get; set; }

   public B SetY(string y)
   {
       this.Y = y;
       return this;
   }
}

然后我想流利地调用方法如下:

B b = new B();

b.SetX("x")
 .SetY("y");

但是这里SetX返回的是 A 的类型,并且 A 没有任何名为 的方法SetY。我该如何设计这样的功能?

4

4 回答 4

4

一种选择是声明SetX为通用扩展方法:

public static T SetX<T>(this T a, string x) where T : A
{
    a.X = x;
    return a;
}

然后你可以这样称呼它:

var newB = b.SetX("foo"); // returns type B
于 2013-04-21T02:12:45.693 回答
3

你可以做一些不同的事情来实现这一点。

第一种是使用泛型,使用类型参数来指定实例的真实类型:

public class A<T> where T:A<T>
{
    public string X { get; private set; }

    public T SetX(string x)
    {
        X = x;
        return (T) this;
    }
}

public class B<T> : A<T>
    where T : B<T>
{
    public string Y { get; private set; }

    public T SetY(string y)
    {
        Y = y;
        return (T) this;
    }
}

public class A : A<A>
{
}

public class B : B<B>
{
}

第二个是,在你的类中,使用关键字B隐藏方法,如下所示:Anew

class A
{
    public string X { get; set; }

    public A SetX(string x)
    {
        this.X = x;
        return this;
    }
}

class B : A
{
    public string Y { get; set; }

    public new B SetX(string x)
    {
        return (B) base.SetX(x);
    }

    public B SetY(string y)
    {
        this.Y = y;
        return this;
    }
}
于 2013-04-21T02:34:14.720 回答
0

使用受保护的:

protected string X { get; set; }
protected A SetX(string x)
{
   this.X = x;
   return this;
}
于 2013-04-21T02:09:34.423 回答
0

这个对我有用:

(b.SetX("1") as B).SetY("2");
于 2013-04-21T05:03:20.267 回答