2014-11-04 127 views
0

我的班級內的許多方法將return this;,這樣我可以在一行內調用多個函數。像a.method1().method2().method3();問題,當我嘗試做一個基類時出現問題。如果我在基類中創建返回T類型的方法,那麼因爲基類的類型不是T,所以我不能再使用return this;。我不能只將返回類型作爲基類,因爲在繼承類中有許多不在基類中的方法。我怎麼解決這個問題?c#返回此通用返回類型的方法

示例代碼:

public class baseClass<T> 
{ 
    public T method1() 
    { 
     //Do stuffs 
     return this;//doesnt work 
    } 
} 

public class inheritedClass:baseClass<inheritedClass> 
{ 
    public inheritedClass method2() 
    { 
     //Do stuffs 
     return this; 
    } 
} 
+2

什麼?發佈代碼。 – 2014-11-04 04:58:31

+0

@HighCore示例代碼發佈 – Steve 2014-11-04 05:03:23

回答

1

可能是這樣

public abstract class BaseClass<T> where T : BaseClass<T> 
{ 
    public T Method1() 
    { 
     //Do stuffs 

     // We are sure any instance of this class is T : BaseClass<T>. 
     // Only exception might be direct instance of BaseClass<T> and that's why we made BaseClass abstract. 
     return (T)this; 
    } 
} 

public class InheritedClass : BaseClass<InheritedClass> 
{ 
    public InheritedClass Method2() 
    { 
     //Do stuffs 
     return this; 
    } 
} 

兩件事情改變。首先,我們仍在鑄造,但是要在基礎課上進行。其次,我們保證這個演員能夠在限制和抽象的地方工作。

+0

不能調用a.method1()。method2()沒有一個鑄造 – Steve 2014-11-04 05:49:48

+0

是的,你可以。你有沒有嘗試過? – 2014-11-04 05:51:14

+0

哦....太棒了,對於以前的評論感到抱歉。介意解釋它爲什麼起作用?看起來像一個編譯器黑客我 – Steve 2014-11-04 05:53:58

1

你的基類的返回類型應該是基類本身,而不是僅僅T.

public class baseClass<T> 
{ 
    public baseClass<T> method1() 
    { 
     //Do stuffs 
     return this; 
    } 
} 
+0

然後我不能做a.method1()。method2()沒有轉換 – Steve 2014-11-04 05:08:09

1

在你的基類的例子,「這」不是一個類型的「T」,而是一種「baseClass {T}」。這就是爲什麼它不起作用。我不知道你在這裏試圖完成什麼,但這可能會編譯...

public class baseClass<T> 
{ 
    public baseClass<T> method1() 
    { 
    return this; 
    } 
} 

public class inheritedClass : baseClass<inheritedClass> 
{ 
    public baseClass<inheritedClass> method2() 
    { 
    return this.method1(); 
    } 
} 

編輯:我現在理解你的問題。這可能比使用繼承更好的整體方法。您可以轉換接口,如果需要的是一個通用的一個...

public interface FluentStuff 
{ 
    FluentStuff method1(); 
    FluentStuff method2(); 
} 

public class MyClass : FluentStuff 
{ 
    public FluentStuff method1() 
    { 
    return this; 
    } 

    public FluentStuff method2() 
    { 
    return this; 
    } 
} 

但是,如果你堅持使用繼承...

public interface FluentStuff 
{ 
    FluentStuff method1(); 
    FluentStuff method2(); 
} 

public abstract class BaseClass : FluentStuff 
{ 
    public virtual FluentStuff method1() 
    { 
    return this; 
    } 

    public abstract FluentStuff method2(); 
} 

public class MyClass : BaseClass, FluentStuff 
{ 
    public override FluentStuff method2() 
    { 
    return this; 
    } 
} 

我非常鼓勵在繼承組成。

泛型實例...

public interface FluentStuff<T> 
{ 
    FluentStuff<T> method1(); 
    FluentStuff<T> method2(); 
} 

public abstract class BaseClass<T> : FluentStuff<T> 
{ 
    public virtual FluentStuff<T> method1() 
    { 
    return this; 
    } 

    public abstract FluentStuff<T> method2(); 
} 

public class MyClass : BaseClass<MyClass>, FluentStuff<MyClass> 
{ 
    public override FluentStuff<MyClass> method2() 
    { 
    return this; 
    } 
} 

最後一個例子另一個問題/關注您發佈...

public class SharedFunctionality 
{ 
    public void DoStuff1() 
    { 
    // common implementation for do stuff 1 
    } 

    public void DoStuff2() 
    { 
    // common implementation for do stuff 2 
    } 
} 

public class MyClass1 
{ 
    private readonly SharedFunctionality sharedFunctionality; 

    public MyClass1() 
    { 
    this.sharedFunctionality = new SharedFunctionality(); 
    } 

    public MyClass1 Method1() 
    { 
    this.sharedFunctionality.DoStuff1(); 
    return this; 
    } 

    public MyClass1 Method2() 
    { 
    this.sharedFunctionality.DoStuff2(); 
    return this; 
    } 
} 

public class MyClass2 
{ 
    private readonly SharedFunctionality sharedFunctionality; 

    public MyClass2() 
    { 
    this.sharedFunctionality = new SharedFunctionality(); 
    } 

    public MyClass2 Method1() 
    { 
    this.sharedFunctionality.DoStuff1(); 
    return this; 
    } 

    public MyClass2 Method2() 
    { 
    this.sharedFunctionality.DoStuff2(); 
    return this; 
    } 

    public MyClass2 Method3() 
    { 
    // do something only this class does 
    return this; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
    MyClass1 c1 = new MyClass1(); 
    c1.Method1().Method2(); 

    MyClass2 c2 = new MyClass2(); 
    c2.Method1().Method2().Method3(); 
    } 
} 
+0

我知道它爲什麼不編譯。我想要完成的是在我的問題中提到的,我希望能夠一次調用多個函數。像a.method1()。method2()。method3()其中method3可能住在內置的類中,並且返回類型必須是被初始化的類本身 – Steve 2014-11-04 05:12:44

+0

我之所以繼承方式的原因是因爲某些方法恰好除了返回類型之外,許多類都是相同的,並且它可以複製/粘貼到所有位置 – Steve 2014-11-04 05:27:17

+0

閱讀本文,構圖提供了與繼承相同的好處,但沒有限制。它使代碼更具可擴展性和可維護性。特別是隨着時間的推移,基類不可避免地變得笨重。 http://en.wikipedia.org/wiki/Composition_over_inheritance – 2014-11-04 05:29:44