繁体   English   中英

如何编写一个函数来返回从C#中的基类派生的任何对象?

[英]How can I write a function that returns any object derived from a base class in C#?

我有一个基类,比如A.

从那个基类我得到了一堆其他类,比如A1,A2,A3 ......

我有一个第三类,比如B.它需要能够返回任何类的方法之一,只要它是从A派生的。

我尝试了以下方法:

public T getObject<T>() where T : A
{
   return (new A1());
}

但是,这会返回一个错误,表示无法将类型A1转换为T.

这种通用回报能否实施?

如果您知道您的类将继承自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();
    }
}

听起来你需要将它与工厂结合起来:

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();
  }
}

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

您可以使用工厂模式获得所需的结果:

public A GetObject (string type) {
     A aObj ;
     if (type == "A1") {
        aobj = new A1 () ;
     else if (type == "A2") {
         aobj = new A2 () ;
     }
     return aObj ;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM