2011-11-14 27 views
1

我在C#項目中使用curiously recurring template pattern(CRTP),但我遇到了一些問題。代碼從上面的鏈接中刪除:使用奇怪的循環模板模式時的返回類型

public abstract class Base<T> where T : Base<T>{ 
    public T FluentMethod() { 
     return (T)(this); 
    } 
} 

public class Derived : Base<Derived> { 
} 

漂亮!問題出現時,我嘗試做這樣的事情:

public class SomeClass 
{ 
    Base<T> GetItem() { /* Definition */ }; 
} 

SomeClass的應該能夠返回基類的任何實現,但當然牛逼這裏已經沒有任何意義,因爲這是另一個類。把派生代替T編譯,但這不是我想要的,因爲我應該能夠返回其他類型的項目,只要它們來自Base。此外,取決於SomeClass對象的狀態,GetItem()可能會返回不同類型的對象,因此使SomeClass通用不是解決方案。

我在這裏丟失了一些明顯的東西,或者在使用CRTP時無法做到這一點?

回答

3

您必須聲明的方法一般:

using System; 
public abstract class Base<T> where T : Base<T> { 
    public T FluentMethod() { 
     return (T)(this); 
    } 
} 

public class Derived : Base<Derived> { 
} 

public class SomeClass { 
    Base<T> GetItem<T>() where T : Base<T> { 
     throw new NotImplementedException(); 
    } 
} 

要使它成爲一個屬性,您必須聲明類本身作爲通用:

public class SomeClass<T> where T : Base<T> { 
    Base<T> GetItem { 
     get { throw new NotImplementedException(); } 
    } 
} 
+0

謝謝!這是我尋找的語法:)這並不能完全解決我的問題的唯一原因是,我沒有寫出所有它......:-s如果GetItem是一個屬性而不是方法.. 。?我似乎無法做到這一點: –

+0

公共基礎項目其中T:基本 {獲得{/ *定義* /}} –

+0

@ChrisRidge:編輯我的回答,看到你的第二個評論太晚了:) :) –

0

不要讓公衆方法通用,否則類型聲明達到另一個級別。爲不同類型的工廠類,如「派生GetDerivedItem()」

public class SomeClass { 
    private Base<T> GetItem<T>() { /*implementation */ } 

    public Derived GetDerivedItem() { 
     return GetItem<Derived>(); 
    } 
} 
+0

這並不能真正解決我的問題,因爲我仍然必須在代碼中指定我想要Derived對象 - 當我稍後可能返回另一個類型時... –

相關問題