简体   繁体   English

通用类工厂问题

[英]Generic class factory problem

Bellow is simplified version of the code I have: 贝娄是我的代码的简化版本:

public interface IControl<T>
{
    T Value { get; }
}

public class BoolControl : IControl<bool>
{
    public bool Value
    {
        get { return true; }
    }
}

public class StringControl : IControl<string>
{
    public string Value
    {
        get { return ""; }
    }
}
public class ControlFactory
{
    public IControl GetControl(string controlType)
    {
        switch (controlType)
        {
            case "Bool":
                return new BoolControl();
            case "String":
                return new StringControl();
        }
        return null;
    }
}

The problem is in GetControl method of ControlFactory class. 问题出在ControlFactory类的GetControl方法中。 Because it returns IControl and I have only IControl<T> that is a generic interface. 因为它返回IControl而我只有IControl <T>这是一个通用接口。 I cannot provide T because in Bool case it's going to bool and in String case it's going to be string. 我不能提供T,因为在Bool情况下它会bool而在String情况下它将是字符串。

Any idea what I need to do to make it work? 知道我需要做些什么来使它工作?

Just derive IControl<T> from IControl . 只需从IControl派生IControl<T>

public interface IControl<T> : IControl
{
    T Value { get; }
}

UPDATE UPDATE

If I missunterstood you, and you don't want a non-generic interface, you will have to make the method GetControl() generic, too. 如果我错过了你的理解,并且你不想要非泛型接口,那么你也必须使方法GetControl()通用。

public IControl<T> GetControl<T>()
{
    if (typeof(T) == typeof(Boolean))
    {
        return new BoolControl(); // Will not compile.
    }
    else if (typeof(T) == typeof(String))
    {
        return new StringControl(); // Will not compile.
    }
    else
    {
        return null;
    }
}

Now you have the problem that the new controls cannot be implicitly casted to IControl<T> and you would have to make this explicit. 现在您遇到的问题是新控件无法隐式转换为IControl<T> ,您必须明确这一点。

public IControl<T> GetControl<T>()
{
    if (typeof(T) == typeof(Boolean))
    {
        return new (IControl<T>)BoolControl();
    }
    else if (typeof(T) == typeof(String))
    {
        return (IControl<T>)new StringControl();
    }
    else
    {
        return null;
    }
}

UPDATE UPDATE

Changed the cast from as IControl<T> to (IControl<T>) . 将演员as IControl<T>as IControl<T>更改为(IControl<T>) This is prefered because it will cause an exception if there is a bug while as IControl<T> silently returns null . 这是首选,因为如果存在错误,它将导致异常,而as IControl<T>静默返回null

public IControl<T> GetControl<T>()
{
    switch (typeof(T).Name)
    {
        case "Bool":
            return (IControl<T>) new BoolControl();
        case "String":
            return (IControl<T>) new StringControl();
    }
    return null;
}

Update; 更新; corrected a couple of errors in the code. 纠正了代码中的几个错误。 Heres a call to get a class: 接下来打电话来上课:

IControl<bool> boolControl = GetControl<bool>();

The return type has to be generic, since, well, it is. 返回类型必须是通用的,因为它确实是。 Think of how you would use this. 想想你将如何使用它。 Returning a strongly typed object obviates the need for a generic factory method. 返回强类型对象不需要通用工厂方法。

Even if you could do it, what's the gain of 即使你能做到,也会有什么好处

IControl<bool> boolControl = controlFactory.GetControl("bool");

or, the one that would work, 或者,那个可行的,

IControl<bool> boolControl = controlFactory.GetControl<bool>("bool");

over a specific 特定的

IControl<bool> boolControl = controlFactory.GetBoolControl("bool");

Either way, you have the switch () at the client side. 无论哪种方式,您在客户端都有switch()。 Either return an object, or have a non-typed IControl interface. 返回一个对象,或者有一个非类型的IControl接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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