C# c中工厂类中的泛型类型实例化#
我有这个结构C# c中工厂类中的泛型类型实例化#,c#,.net,generics,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 ne
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();
}
}
公共类基
{
}
公共A类:基本类
{
}
B类公共服务:基本服务
{
}
公营工厂
{
公共基GetInstance(int类型)
{
如果(类型==0)
返回新的A();
其他的
返回新的B();
}
}
但是我得到了关于的编译错误,无法将表达式类型B转换为返回类型Base
,为什么我会得到这个错误?我怎样才能修好它
为什么我会犯这个错误
出现此错误是因为当类型为0
时,编译器无法在编译时验证T
是否为string
,或者T
是否为int
。就编译器而言,T
可以是任何类型
我怎样才能修好它
您需要将结果强制转换为Base
,如下所示:
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>;
}
}
另一种可能适合您的方法(取决于您的需求)是删除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 GetInstance()
{
if(typeof(T)=typeof(string))
返回(基)(对象)新的A();
否则如果(typeof(T)=typeof(int))
返回(基本)(对象)新B();
抛出新ArgumentException(“不支持的类型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 GetInstance()
{
if(typeof(T)=typeof(int))
返回新的A()作为基函数;
else if(typeof(T)=typeof(string))
返回新的B()作为基函数;
抛出新的ArgumentException(“不支持的类型:+typeof(T).ToString());
}
但泛型方法中的类型检查和分支通常是一种代码味道。更安全的选择是采用不同的方法:
public Base<int> GetIntInstance()
{
return new A();
}
public Base<string> GetStringInstance()
{
return new B();
}
public Base GetIntInstance()
{
返回新的A();
}
公共基GetStringInstance()
{
返回新的B();
}
注意
- 代码行数相同(如果不计算括号,则更少)
- 调用语法几乎相同(
GetIntInstance
vsGetInstance
)
- 不存在使用不受支持的泛型类型参数的风险
可以显示调用工厂的代码吗?这不起作用,因为A
和B
不是从相同的基类型派生的(除了Object
),因为base
和base
在继承层次结构中是不相关的(除了作为相同的基类共享Object
);据我所知,这无法直接修复。您的代码不是泛型的-您返回的是基于特定输入的特定类型,与该类型无关。泛型的要点是使用客户机选择的任何类型(受定义的约束)。@StephenBrickner这是编译时错误,虽然这可能在语法上起作用(因此+1),但我看不出它的要点;调用方必须明确知道所需的类型,因此工厂不会提供真正的抽象。是否可以使用约束来指导编译器where T:Base
(不知道怎么做)?@Codor,我只是简单地向OP解释编译器为什么抱怨,并给他一个如何修复它的直接答案。@Sinatr,我认为你做不到that@Codor,这就是我直接回答的原因。我们不知道OP到底想要什么,直到他对答案发表评论:)
public Base<int> GetIntInstance()
{
return new A();
}
public Base<string> GetStringInstance()
{
return new B();
}