我有一个基类,比如A。
从那个基类我得到了一堆其他类,比如A1,A2,A3 ......
我有第三个类,比如说B.只要它来自A,它就需要能够返回任何类的方法之一。
我尝试了以下内容:
public T getObject<T>() where T : A
{
return (new A1());
}
但是,这会返回一个错误,表示无法将A1类型转换为T.
这种通用回报能否实施?
答案 0 :(得分:2)
如果你知道你的班级将继承A,但不需要知道确切的类型,那么你就不需要泛型:
public A getObject()
{
return new A1();
}
如果您的示例已编译,则意味着您可以调用
A2 result = getObject<A2>();
但是getObject
的实施始终会返回new A1()
。由于A1
没有继承A2
,因此这是错误的。
听起来你可能希望根据某些神秘逻辑的结果返回不同的类型。这很好,仍然不需要泛型:
public A getObject()
{
switch(MysteryLogic())
{
case MysteryLogicResult.One:
return new A1();
case MysteryLogicResult.Two:
return new A2();
case MysteryLogicResult.Three:
return new A3();
}
}
答案 1 :(得分:2)
听起来你需要将它与工厂结合起来:
public interface IAFactory
{
A Build();
}
然后你可以改变你的通用方法:
public A getObject<T>() where T : new, IAFactory
{
return getObject(new T()
}
public A getObject<T>(T factory) where T : IAFactory
{
return factory.Build();
}
您需要更改A1,A2的实现:
public class A1 : A, IAFactory
{
public A1 Build(){
//Logic for constructing A1
}
}
或者创建专门的课程:
public class A1Factory : IAFactory
{
public A1 Build(){
//Logic for constructing A1
}
}
然后你可以打电话给你的方法:
public class Test
{
public void CallBMethod()
{
//option 1
A option1 = new B().getObject<A1>();
//option 2
A option2 = new B().getObject<A1Factory>();
//Or skip the B.getObject method and access factory directly:
A a1 = new A1Factory().Build();
A a2 = new A2Factory().Build();
}
}
答案 2 :(得分:1)
TL; DR:您必须返回T,因为这是您为方法声明的返回类型。
如果你返回A1,它看起来应该像你说的那样工作。但是你忘记了你也可以通过传入A2来调用方法,在这种情况下返回A1是无效的:
var myObject = getObject<A1>(); // this would have worked
var myObject = getObject<A2>(); // this can not work
这将失败,因为A1不能分配给A2类型。因为第二种情况不起作用,编译器不允许你这样做。
那么正确的方法是返回新的T:
public T getObject<T>() where T : A
{
return (new T());
}
var myObject = getObject<A1>(); // works
var myObject = getObject<A2>(); // also works
答案 3 :(得分:1)
您可以使用工厂模式获得所需的结果:
public A GetObject (string type) {
A aObj ;
if (type == "A1") {
aobj = new A1 () ;
else if (type == "A2") {
aobj = new A2 () ;
}
return aObj ;
}