2016-02-29 79 views
1

我有一个界面如何创建工厂为通用类

public interface IProperty<T> 
{  
    T Data { get; set; } 
} 

public abstract class SomeAbsProperty<T> : IProperty<T> where T : class 
{ 
    protected SomeAbsProperty(int param1) {} 
    public abstract T GetData(); 
    public I Data { get; set; } 
} 

而且我有一个基于SomeAbsProperty类childres类的列表 他们看起来像(简单的例子)

public sealed class ChildrenProperties : SomeAbsProperty<SomeClasss> 
{ 
    public ChildrenProperties(int param1):base(param1) {} 
    public override object GetData() 
    { 
     return new SomeClasss() 
    } 
} 

我会喜欢有一些工厂可以建立基于某种类型的特定课程

public static class MyFactory 
{ 
    public static SomeAbsProperty<T> CreateObject<T>(PropertyName property) where T : class 
    { 
     switch (property) 
     { 
      case PropertyName.p1: 
       return new ChildrenProperties1(siteSettings, packageDateContext); 
      case PropertyName.p2: 
       return new ChildrenProperties(siteSettings, packageDateContext); 
      case PropertyName.p3: 
       return new ChildrenProperties2(siteSettings, packageDateContext); 
      case PropertyName.p4: 
       return new ChildrenProperties3(siteSettings, packageDateContext); 
      default: 
       return null; 
     } 
    } 
} 

但compelator不能我clases转换为SomeAbsProperty 什么是正确的行为吗?

+2

只有一个代码应该决定什么具体的类,我们所需要的。它可以是CreateObject 或“返回新SomeClass()”。如果我们调用的CreateObject ,并通过对应于ChildrenProperties3属性 什么代码会做什么? –

回答

1

您可以使用as铸造SomeAbsProperty<T>泛型类,像

return new ChildrenProperties(10) as SomeAbsProperty<T>; 

中,当然,你必须确保ChildrenProperties确实SomeAbsProperty(你知道这是你写的基类和工厂类) 。你不能使用显式的编译时间转换。如果创建实例的工厂只取决于泛型参数(只有当所有特化具有不同的参数T;我不确定这是否是您的情况),也许它会更好。喜欢的东西:

 public static SomeAbsProperty<T> CreateObject<T>() where T : class 
     { 
      Type type = typeof(T); 
      if (type == typeof(object)) 
      { 
       return new ChildrenProperties() as SomeAbsProperty<T>; 
      } 
      else if (type == typeof(string)) 
      { 
       return new ChildrenPropertiesString() as SomeAbsProperty<T>; 
      } 
      else 
      { 
       return null; 
      } 
     } 

...那么你可以拨打厂家的东西,如:

SomeAbsProperty<object> h = MyFactory.CreateObject<object>(); 
Console.WriteLine(h.GetType().ToString()); 
SomeAbsProperty<string> h2 = MyFactory.CreateObject<string>(); 
Console.WriteLine(h2.GetType().ToString()); 
+1

这将编译,但风险在于,如果'ChildrenProperties(10)'不是'SomeAbsProperty '(你可以不知道在编译时),那么你会得到'null'回来。 –

+0

是的,我同意,但他创造了他明知是SomeAbsProperty ChildrenProperties类,所以我觉得这不应该是一个问题 – Igor

+0

但你不知道什么是'T'被用来调用的方法,所以没有保证他们匹配。 –