[英]Generic type instantiation in Factory class in c#
I have this structure 我有这个结构
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();
}
}
but I get compile error about Cannot convert expression type B to return type Base<T>
, why I get this error? 但我收到编译错误
Cannot convert expression type B to return type Base<T>
,为什么我收到此错误? and how can I fix it? 我该如何解决?
why I get this error?
为什么我会收到此错误?
You are getting this error because the compiler cannot verify at compile time that T
is string
when type
is 0
or that T
is int
otherwise. 您收到此错误是因为编译器无法在编译时验证
T
是string
时type
为0
或T
是否则为int
。 As far as the compiler is concerned, T
could be any type. 就编译器而言,
T
可以是任何类型。
and how can I fix it?
我该如何解决?
You need to cast the result to Base<T>
like this: 您需要将结果转换为
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>;
}
}
Which will cause this method to return null
if T
is not the correct type. 如果
T
不是正确的类型,这将导致此方法返回null
。
The following alternative will throw a InvalidCastException
exception if T
is not the correct type: 如果
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();
}
}
Another approach that might work for you (depending on your requirements) is to remove the type
parameter and to depend completely on T
to determine the type of object that you need to return. 另一种可能适合您的方法(取决于您的要求)是删除
type
参数并完全依赖于T
来确定您需要返回的对象类型。 Here is an example: 这是一个例子:
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");
}
Your method is not generic because you're returning a non-generic type based on the type that's passed in (whether you use a code for the type or the actual type). 您的方法不是通用的,因为您根据传入的类型返回非泛型类型(无论您是使用类型的代码还是实际类型)。 At best you could define a relationship between the type passed in and the return type:
最好你可以定义传入的类型和返回类型之间的关系:
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());
}
But type checking and branching in a generic method is generally a code smell. 但是,通用方法中的类型检查和分支通常是代码气味。 A safer option would be to have different methods:
更安全的选择是使用不同的方法:
public Base<int> GetIntInstance()
{
return new A();
}
public Base<string> GetStringInstance()
{
return new B();
}
Note that 注意
GetIntInstance
vs GetInstance<int>
) GetIntInstance
vs GetInstance<int>
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.