C# 如何为泛型类创建工厂

C# 如何为泛型类创建工厂,c#,C#,我有下一个接口 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(); p

我有下一个接口

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; }
}
公共接口IProperty
{       
T数据{get;set;}
}
公共抽象类SomeAbsProperty:IProperty其中T:class
{
受保护的SomeAbsProperty(int param1){}
公共摘要T GetData();
公共I数据{get;set;}
}
我有一个基于SomeAbsProperty类的childres类列表 它们看起来像(简单的例子)

公共密封类ChildrenProperties:SomeAbsProperty
{
公共ChildrenProperties(int param1):基(param1){}
公共重写对象GetData()
{
返回新的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;
        }
    }
}
公共静态类MyFactory
{
公共静态SomeAbsProperty CreateObject(PropertyName属性),其中T:class
{
交换机(属性)
{
案例属性名称.p1:
返回新的ChildrenProperties1(站点设置、packageDateContext);
案例PropertyName.p2:
返回新的ChildrenProperties(siteSettings、packageDateContext);
案例属性名称.p3:
返回新的ChildrenProperties2(站点设置、packageDateContext);
案例属性名称.p4:
返回新的ChildrenProperties3(站点设置、packageDateContext);
违约:
返回null;
}
}
}
但主持人无法将我的课程转换为其他课程
这里的正确行为是什么?

您可以使用
as
转换为
SomeAbsProperty
泛型类,例如

return new ChildrenProperties(10) as SomeAbsProperty<T>;
将新的ChildrenProperties(10)作为SomeAbsProperty返回;
当然,您必须确保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());
public static SomeAbsProperty CreateObject(),其中T:class
{
类型=类型(T);
if(type==typeof(object))
{
将新的ChildrenProperties()作为SomeAbsProperty返回;
}
else if(type==typeof(string))
{
将新的ChildrenPropertiesString()作为SomeAbsProperty返回;
}
其他的
{
返回null;
}
}
。。。然后,您可以通过以下方式呼叫工厂:

        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());
SomeAbsProperty h=MyFactory.CreateObject();
WriteLine(h.GetType().ToString());
SomeAbsProperty h2=MyFactory.CreateObject();
WriteLine(h2.GetType().ToString());

只有一个代码可以决定我们需要什么样的具体类。它是CreateObject或“returnnewsomeClass()”。如果我们调用CreateObject并传递一个与ChildrenProperties3对应的属性,代码会做什么?这将进行编译,但风险是如果
ChildrenProperties(10)
不是
SomeAbsProperty
(编译时您无法知道),那么您将返回
null
。是的,我同意,但是他创建了ChildrenProperties类,他知道这个类是SomeAbsProperty,所以我认为这不应该是个问题,但是你不知道调用这个方法时使用了什么
t
,所以不能保证它们匹配。你说得很好。我已经更新了我的答案,它只提出了用于解析应该实例化哪个类的泛型参数。若作者有所有不同的泛型类专门化,那个么这对他来说可能会更好