2012-01-02 73 views
2

我正在尋找一個C#替代C++ typedefs或特定類在特定情況下。我知道沒有直接的等價物,但是對於這個特定的問題,可能還有其他解決方案?C#中的靜態派生類型?

這是我想要做的。我正在編寫一個有三種相關類型的框架。視圖,後備存儲和工廠。所有三個接口將會有多個實現。視圖與工廠之間存在1-1關係,視圖與存儲之間存在1-N關係。一個具體的impl。的框架看起來像這樣:

Storage : IStorage<int> ... 

View : IView<Storage> ... // And IView<T> : IViewNonGeneric further up.. 

Factory : IFactory<Storage> { 
    // This needs to take a concrete storage type as arg 
    IViewNonGeneric CreateView(Storage s) ... 

    Storage CreateStorage() ... 
} 

View類是框架用戶最重要的類;其他的都是一些實現細節。因此,根據View類來定義工廠(而不是根據存儲)看起來更自然。在C++中,這將是簡單的,只需添加一個typedef到視圖,並在工廠裏使用它,就像這樣:

class IView<typename T> { typedef T TStorage; ... 

class IFactory<typename T> { 
    IViewNonGeneric CreateView(typename T::TStorage s) ... 

在C#中,我們顯然不具備的typedef或traits類。有沒有其他的方式來達到預期的效果?也就是說,是否可以使用View作爲Factory的通用參數,並從View中派生出具體的Source類型?

+1

是不夠的,使用'where'仿製藥申報約束的類型必須實施? – Tigran 2012-01-02 10:38:03

回答

3

C#中的泛型絕對不如C++中的模板強大。但是,C#確實有一些非常強大的C++沒有的東西:反射。

在視圖類中定義一個方法(靜態或實例)應該很容易,該方法將返回存儲類的具體類型。然後,您可以使用Type.GetConstructor動態查找存儲類的構造函數,並使用ConstructorInfo.Invoke方法調用它。

此外,您可以探索使用您可以分配給視圖類的自定義屬性。怎麼樣是這樣的:

[StorageType(typeof(MyStorage1) ] 
class MyView1 { ... } 

然後使用反思的typeof(MyView1),看它是否已StorageTypeAttribute與它相關聯。

+0

謝謝你的建議。這可能是我得到的最接近的,但不幸的是它不會工作,因爲它需要更改工廠功能簽名。 – 4ZM 2012-01-02 10:40:27

+0

不知道我跟着你爲什麼你不得不改變工廠功能簽名。你可以使工廠成爲一個通用的類。或者...您可以將反射與屬性結合起來 – DXM 2012-01-02 10:46:56

+0

在IFactory 接口中我有:T CreateStorage()(其中T:IStorage)。什麼信號。如果IFactory接口的通用參數被改變來表示一個視圖而不是存儲器,這個函數的功能是什麼? – 4ZM 2012-01-02 11:12:15

0

我想是你想要什麼:

public interface IStorage<T> 
{ 
} 

public class IntStorage : IStorage<int> 
{ 
} 

public interface IFactory<S, T> where S : IStorage<T> 
{ 
    IView<S, T> CreateView(S storage); 
} 

public interface IViewNonGeneric 
{ 
} 
public interface IView<S, T> : IViewNonGeneric where S : IStorage<T> 
{ 
} 

public class IntView : IView<IntStorage, int> 
{ 
} 

public class IntFactory : IFactory<IntStorage, int> 
{ 
    public IntView CreateView(IntStorage storage) 
    { 
     // create the view 
    } 
    // private interface implementation 
    IView<IntStorage, int> IFactory<IntStorage, int>.CreateView(IntStorage storage) 
    { 
     return CreateView(storage); 
    } 
} 

...