2010-07-28 150 views
2

我很可能會被想象的東西,但我似乎在Java中記得,我可以聲明一個字段或參數這樣:限制類型參數在C#泛型

public class BarHandler{ 

    public Class<? extends Foo> fooType; 

    public ProcessedBar Process(string xml){ 
     Foo foo = fooType.GetInstance(); 
     return foo.process(xml) 
    } 
} 

這可能是工廠式的有用例如,您必須能夠生成相關類型的新實例。

我想弄清楚在C#中是否有類似的東西,或者如果可能這只是Java中可用的東西。

回答

1

下面是280Z28的答案變化。我已將「Type」類重命名爲「Factory」,因爲在我的版本中,它公開了GetInstance方法,而不是Type類型的Value屬性。這使用2個通用參數和通用約束來執行原始答案的Type類構造函數中的規則。

public abstract class Factory<T> 
{ 
    public abstract T GetInstance(); 
} 

public sealed class IoCFactory<T, TDerived> : Factory<T> 
    where TDerived : T // compiler enforces that TDerived derives from T 
{ 
    public override T GetInstance() 
    { 
     // TODO: retrieve instance of TDerived from IoC container such as Spring.NET, StructureMap, Unity, etc. 
     throw new NotImplementedException(); 
    } 
} 

public sealed class ActivatorFactory<T, TDerived> : Factory<T> 
    where TDerived : T, new() // compiler enforces that TDerived derives from T and that it has a parameterless constructor 
{ 
    public override T GetInstance() 
    { 
     return Activator.CreateInstance<TDerived>(); 
    } 
} 

public class BarHandler 
{ 
    public Factory<Foo> fooFactory { get; set; } 

    public ProcessedBar Process(string xml) 
    { 
     Foo foo = fooFactory.GetInstance(); 
     return foo.Process(xml); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     BarHandler handler = new BarHandler(); 

     handler.fooFactory = new ActivatorFactory<Foo, Bar>(); 

     var processedResult = handler.Process("<bar>Yar!</bar>"); 
    } 
} 
5

是的,請參閱generic constraints。相當於你的例子是:你的編輯

public class SomeClass<T> 
    where T : Foo 
{ 
    private T fooType; 
} 

編輯AFTER:我相信你指的是wildcards,在這種情況下,你應該閱讀相對於仿製藥大約covariance and contravariance

+0

正如我在TreDubZedd中所說的那樣,我確實已經找到了通用約束項目,並且在獲得的課程級別上進行了操作。我正在專門研究類型類和限制我願意存儲的類型的方法。 – Matt 2010-07-28 17:33:20

+0

據此編輯。 – 2010-07-28 17:34:48

1
public class GenericClass<T> where T : Foo 
+0

正確的想法錯誤的級別。我發現如何用泛型類來做到這一點,但我想用一個參數或類型的字段來做到這一點。我正在擴展我的例子來解釋。 – Matt 2010-07-28 17:28:25

1

你可以使用一個非常簡單的包裝了這個註解和廉價的運行時檢查:

public sealed class Type<T> 
{ 
    public Type(Type type) 
    { 
     if (type == null) 
      throw new ArgumentNullException("type"); 
     if (!typeof(T).IsAssignableFrom(type)) 
      throw new ArgumentException(string.Format("The specified type must be assignable to '{0}'.", typeof(T).FullName)); 

     this.Value = type; 
    } 

    public Type Value 
    { 
     get; 
     private set; 
    } 
} 

使用Activator.CreateInstance實際創建類型的實例。假設FooDerived源自Foo

Type<Foo> fooType = new Type<Foo>(typeof(FooDerived)); 
Activator.CreateInstance(fooType.Value);