2013-04-21 65 views
2

我在基类中有一个方法,它应该返回类型为derivation类型的自实例。例如:如何从基类型中声明的方法返回派生类型

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 has'nt命名SetY任何方法。我如何设计这样的功能?

+4

http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – SLaks 2013-04-21 02:12:11

回答

3

有是可以做到这一点的两件不同的事情。

第一种是使用泛型,使用类型参数来指定实际类型实例的:使用new关键字

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类,隐藏的方法,从A ,像这样:

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; 
    } 
} 
+0

第一种选择是我已经知道的,第二种选择是我所要求的。我认为你应该重新排列选项来说清楚。 – 2013-04-21 07:48:43

+0

@HalilIbrahim我改变了你问的顺序。很高兴它有帮助 – mlorbetske 2013-04-21 17:16:45

0

使用保护:

protected string X { get; set; } 
protected A SetX(string x) 
{ 
    this.X = x; 
    return this; 
} 
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 
+0

很酷的解决方案,但在我的研究中,A和B都是通用类,我无法在使用扩展方法时解析泛型类型参数。 – 2013-04-21 07:43:27

0

这一个为我工作:

(b.SetX("1") as B).SetY("2"); 
相关问题