我有一个场景,其中有两个类分别使用方法MethodA和MethodB来说ClassA和ClassB。我必须编写泛型方法,根据某个整数变量x的条件返回上述类的对象实例。当我尝试下面的代码时,出现“无法将ClassA隐式转换为T”或“无法将ClassB隐式转换为T”的错误
public ClassA
{
public void MethodA()
{
//method implementation
}
}
public ClassB
{
public void MethodB()
{
//method implementation
}
}
通用方法
public T MethodGeneric<T>()
{
int x;
ClassA objectA = new ClassA();
ClassB objectB = new ClassB();
if(x==2)
{
return objectA;
}
else
{
return objectB;
}
}
答案 0 :(得分:4)
问题是T
不是ClassA
,也不是ClassB
。
您可以尝试通过强制转换来处理此问题,如下所示:
public static T MethodGeneric<T>() where T : class
{
int x = 2;
ClassA objectA = new ClassA();
ClassB objectB = new ClassB();
if (x == 2)
{
return objectA as T;
}
else
{
return objectB as T;
}
}
但是,如果有人拨打MethodGeneric<ClassC>()
,除了在这种情况下返回null
之外,这不会保护您。
如果ClassA
和ClassB
都来自相同的基类或接口,则可以使这更安全,因为您可以设置一个通用约束来减少出错的可能性。然而,这仍然不是一种完全安全的工作方式,因为仿制药不合适。最好让两个类都实现一个接口(即:IClassBase
),然后不使用泛型,但返回接口:
public IClassBase CreateInstance()
{
//...
return objectA; // This will work fine, provided ClassA implements IClassBase
}
答案 1 :(得分:0)
从你关闭的this double-post开始,你就近了。您将object
作为类型参数传递,它将在您的案例中再次返回T
object
。这就是为什么你不能使用ClassA
对象上定义的属性。相反,您应该传递所需的类型,例如ClassB
或ClassC
。可能是这样的:
public T getObject<T>(int i) where T : ClassA
{
if(i == 1)
{
ClassB objB = new ClassB();
return objB as T;
}
else
{
ClassC objC = new ClassC();
return objC as T;
}
}
public static void main()
{
var obj = getObject<ClassB>(5); //which wont work anyway since i == 5 !!
obj.aValue = 20;
obj.bValue = 30;
//obj.cValue = 40; this wont work since obj is of type ClassB
//or
var obj = getObject<ClassC>(5);
obj.aValue = 20;
//obj.bValue = 30; this wont work since obj is of type ClassC now
obj.cValue = 40;
}
我不确定你为什么要检查变量int i
来决定应该返回的类型。这不是泛型的真正用法。真正使用泛型可能看起来像:
public T getObject<T>(int i) where T : ClassA
{
return new T(); //without the use of int i
}
如果int i
决定返回哪个对象,那么为什么要使用泛型呢?你很可能会这样做:
public ClassA getObject(int i)
{
if(i == 1)
{
ClassB objB = new ClassB();
return objB;
}
else
{
ClassC objC = new ClassC();
return objC;
}
}
public static void main()
{
var obj = getObject(5);
if (obj is ClassB)
{
obj.aValue = 20;
obj.bValue = 30;
//obj.cValue = 40; this wont work since obj is of type ClassB
}
//or
var obj = getObject(5);
if (obj is ClassC)
{
obj.aValue = 20;
//obj.bValue = 30; this wont work since obj is of type ClassC
obj.cValue = 40;
}
}
但要抓住的是你必须从来电方(Main)检查类型。
如果您想在bValue
和cValue
对象上分配属性ClassB
和ClassC
,那么您应该在ClassA
中编写这些属性。
此外,您只使用get
访问者,还需要set
来分配值。