简体   繁体   中英

How to create Factory for Generic Class

I have next interface

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; }
}

And I have list of childres classes that based on SomeAbsProperty class they looks like (simple example)

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

I would like to have some factory that would build specific class based on some type

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;
        }
    }
}

but compelator can't convert my clases to SomeAbsProperty what would be correct behavior here ?

You can use as casting to SomeAbsProperty<T> generic class, something like

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

Of-course you must be sure that ChildrenProperties is indeed SomeAbsProperty (which you know it is if you wrote base classes and factory class). You can not use explicit compile time casting.

Edit: Maybe its better if factory which creates instances only depends on generic parameter (this will work only if all specializations have different parameter T; I'm not sure if that is your situation). Something like:

        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;
            }
        }

... then you can call factory with something like:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM