2015-11-05 39 views
-1

我有一個叫做PointValue,PointValue的類,他的繼承者只能通過接收一個浮點參數的參數化構造函數創建。泛型類c中的函數專業化#

我有一個泛型類,代表點的列表,模板類型必須從PointValue繼承。

我需要的一個功能將有能力添加點列表,因爲我不能強制使用模板參數化的構造函數。我的功能獲得pointValueCreator創建新的點。

PointList<PointValue> bla = new PointList<PointValue>(); 

我可以打電話給我的功能是這樣的::

public class PointList<PointValueT> where PointValueT : PointValue 
{ 
    public void addPointToList(float f, Func<float,PointValueT> pointValueCreator) 
    { 
    // do something to f and then add a new point: 
    mylist.Add(pointValueCreator(f)); 
    } 
} 
所以,現在如果我有這樣的事情

bla.addPointToList(f, (myfloat) => new PointValue(myfloat)); 

我的問題是如何爲addPointToList爲創建專業化的我繼承人,以避免傳遞的創造者。

類似:

public void addPointToList(float f) 
{ 
this.addPointToList(f, (myfloat) => new PointValue(myfloat)); 
} 

我試圖做到這一點,但是編譯器說: 無法隱式轉換類型「PointValue」到「PointValueT」。一個明確的轉換存在(你是否缺少演員?)

我明白,c#沒有專業化,如果是這樣的話,也許一些「設計」技巧可以幫助我嗎? 假設我有PointValueA和PointValueB inherting,我如何避免手動爲每個人傳遞創作者?

+0

刪除''。 – Amit

+2

在c#中,它們被稱爲_generics_ **而非**模板。 – MickyD

+0

嗨@Amit,我編輯了這個問題,我不小心寫了它。問題仍然是一樣的。 – OopsUser

回答

1

您不能在C#中使用C++中的模板來專門化C#中的泛型。

能夠在約束中指定構造函數參數(即where PointValueT : PointValue, new(float))會很好,但語言不允許這樣做。

有一對夫婦的解決方案來實現你想要的:

1:使用一個創作者的圖案像你已經做

2:而不是在構造函數中設置浮動,將其設置爲屬性。

public class PointValue 
{ 
    public float Value { get; set; } 
} 

public class PointList<PointValueT> 
    where PointValueT : PointValue, new() 
{ 
    public void addPointToList(float f) 
    { 
    // do something to f and then add a new point: 
    mylist.Add(new PointValueT { Value = f }); 
    } 
} 

這確實意味着你不能讓你的PointValue不可變。

1

您可以排序的專門使用繼承

public class PointValueList : PointList<PointValue> 
{ 
    public void addPointToList(float f) 
    { 
     addPointToList(f, (myfloat) => new PointValue(myfloat)); 
    } 
} 

,然後在新的遺傳性或專業類,你可以叫

bla.addPointToList(f); 

而且根據你的需要,你可以使基類抽象並在基類中聲明

public abstract void addPointToList(float f); 

然後重寫在派生的專業化類

但是,正如Enigmativity建議的那樣,通過構造函數傳遞工廠更有意義,至少在這個簡單的例子中。

2

我原以爲處理這個問題最基本的方法是讓工廠通過構造函數,而不是每次調用addPointToList

public class PointList<PointValueT> where PointValueT : PointValue 
{ 
    public PointList(Func<float, PointValueT> pointValueCreator) 
    { 
     this.pointValueCreator = pointValueCreator; 
    } 
    Func<float, PointValueT> pointValueCreator; 
    private List<PointValueT> mylist = new List<PointValueT>(); 
    public void addPointToList(float f) 
    { 
     mylist.Add(pointValueCreator(f)); 
    } 
} 

這則這樣調用:

PointList<PointValue> bla = new PointList<PointValue>((myfloat) => new PointValue(myfloat)); 

bla.addPointToList(f);