c#中Factory类中的泛型类型实例化
本文关键字:泛型类型 实例化 Factory | 更新日期: 2023-09-27 18:26:16
我有这个结构
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>
的编译错误,为什么我得到这个错误?我该怎么修?
为什么我会出现这个错误?
出现此错误的原因是,当type
为0
时,编译器无法在编译时验证T
为string
,否则无法验证T
为int
。就编译器而言,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>;
}
}
如果T
不是正确的类型,这将导致此方法返回null
。
如果T
不是正确的类型,以下备选方案将引发InvalidCastException
异常:
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");
}
您的方法不是泛型的,因为您返回的是基于传入类型的非泛型类型(无论您使用的是类型代码还是实际类型代码)最多您可以定义传入类型和返回类型之间的关系:
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
与GetInstance<int>
) - 不存在使用不受支持的泛型类型参数的风险