c#中Factory类中的泛型类型实例化

时间:2015-12-09 14:07:11

标签: c# .net generics

我有这个结构

public class Base<T>
{

}

public class A : Base<string>
{

}

public class B : Base<int>
{

}

public class Factory
{
    public Base<T> GetInstance<T>(int type)
    {
        if (type == 0)
            return new A();
        else
            return new B();
    }
}

但我收到关于Cannot convert expression type B to return type Base<T>的编译错误,为什么我收到此错误?我该如何解决?

2 个答案:

答案 0 :(得分:2)

  

为什么我会收到此错误?

您收到此错误是因为当Tstringtype为{{0时,编译器无法在编译时验证Tint 1}}否则。就编译器而言,T可以是任何类型。

  

我该如何解决?

您需要将结果转换为Base<T>,如下所示:

public class Factory
{
    public Base<T> GetInstance<T>(int type)
    {
        if (type == 0)
            return new A() as Base<T>;
        else
            return new B() as Base<T>;
    }
}

如果null不正确,则会导致此方法返回T

如果InvalidCastException的类型不正确,则以下备选方案将引发T异常:

public class Factory
{
    public Base<T> GetInstance<T>(int type)
    {
        if (type == 0)
            return (Base<T>)(object)new A();
        else
            return (Base<T>)(object)new B();
    }
}

另一种可能适合您的方法(取决于您的要求)是删除type参数并完全依赖T来确定您需要返回的对象类型。这是一个例子:

public Base<T> GetInstance<T>()
{
    if (typeof(T) == typeof(string))
        return (Base<T>)(object)new A();
    else if(typeof(T) == typeof(int))
        return (Base<T>)(object)new B();

    throw new ArgumentException("Unsupported type T");
}

答案 1 :(得分:1)

您的方法不是通用的,因为您根据传入的类型返回非泛型类型(无论您使用的是类型还是实际类型的代码)。 最好你可以定义传入的类型和返回类型之间的关系:

public Base<T> GetInstance<T>()
{
    if (typeof(T) == typeof(int))
        return new A() as Base<T>;
    else if (typeof(T) == typeof(string))
        return new B() as Base<T>;
    throw new ArgumentException("Unsupported type: " + typeof(T).ToString());
}

但是通用方法中的类型检查和分支通常是代码气味。更安全的选择是采用不同的方法:

public Base<int> GetIntInstance()
{
    return new A();
}
public Base<string> GetStringInstance()
{
    return new B();
}

请注意

  • 代码行数相同(如果不算括号,则减少)
  • 调用语法几乎相同(GetIntInstance vs GetInstance<int>
  • 不存在使用不受支持的泛型类型参数的风险