2010-07-28 147 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);