在c#

时间:2018-03-04 20:13:26

标签: c# asp.net generics interface factory-pattern

我正在使用Factory模式,其中,基于接口,它将创建并返回新的concreate对象。我使用Generic Type并使用switch为不同的concreate对象检查它。这是我的班级布局。

public class Factory<T>
{
     public T Instance()
     {
         switch(T)
         {
             case IUser:
                return new Domain.User();
                break;
             case IProduct:
                return new Domain.Product();
                break;
         }
     }
}

但是这给我一个错误:

'T' is a type, which is not valid in the given context

Cannot implicitly convert type 'Domain.User' to 'T'

这就是我的客户端代码调用上面的Factory类的方法。

private readonly Factory<IUser> factory = new Factory<IUser>();
IUser oUser = factory.Instance();

1 个答案:

答案 0 :(得分:2)

您不能在switch中使用类型,但可以启用类型名称:

switch(typeof(T).Name) {
    case nameof(IUser):
        return new Domain.User();
        break;
    case nameof(IProduct):
        return new Domain.Product();
        break;
}

请注意,这是一个非常不灵活的解决方案,因为向工厂添加新类型需要重新编译包含switch的罚款。

更好的方法是制作工厂接受的类型注册表,或使用现有的解决方案,例如autofac。

以下是注册工厂的骨干实现:

class Factory {
    private readonly IDictionary<Type,Func<object>> registry = new Dictionary<Type,Func<object>>();
    public void Register<T>(Func<T> make) {
        registry.Add(typeof(T), () => (object)make());
    }
    public T Instance<T>() {
        return (T)registry[typeof(T)]();
    }
}

您可以按如下方式使用工厂:

Factory f = new Factory();
f.Register<IUser>(() => new User());
f.Register<IProduct>(() => new Product());
IUser u = f.Instance<IUser>();

Demo.