从父类方法返回子类的类型

时间:2015-01-16 21:29:17

标签: c# inheritance

如果我有一个班级A,以及从B继承的班级CDA,有没有办法写一个A中的方法,当在子类上调用时,它将具有子类的返回类型?

所以,如果我要A.myMethod(),我会得到A,如果我要做B.myMethod(),我会得到B的实例?< / p>

5 个答案:

答案 0 :(得分:2)

您所要求的并不是严格的多态性,因为您要覆盖返回类型,因此具有与原始方法不同的签名。真正的多态性不会改变这个签名,因此您所要求的并不是C#中的第一类情况。

话虽如此,至少有两种方法。

最简单的方法是覆盖该方法,使用new关键字隐藏原始方法,允许您更改签名。

public new B MyMethod() { return (B)(base.MyMethod()); }

这将允许B的任何用法返回B,但实际上不会覆盖A.MyMethod的行为。避免在代码中重复进行类型转换可能很有用。

如果你还需要覆盖方法以允许它返回类型为B的对象,则这不能在同一个类中共存,因为编译器看到相同的签名(相同的名称,相同的参数,即使返回类型明显不同。)

第二种方式称为静态多态性,如果您正在使用某种工厂,它非常有用,但是要解决这个问题可能非常棘手,因为它只允许一个级别的实际的继承。静态多态类型以具有受其自身约束的通用组件的类型开始:

public class A<TSelf> where TSelf : A<TSelf> { }
public class B : A<B> { }

这意味着你的方法可以返回类型为TSelf的n对象,即使这是一个抽象方法,所以每个继承者都必须处理构造函数,但是从B继承的任何类都有一个更难的时候覆盖它,因为它继承自A<B>,而不是A<C>

答案 1 :(得分:0)

假设您只想在myMethod中声明方法A,您可以执行以下操作:

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var a = new A();
            var b = new B();

            Console.WriteLine(a.M());
            Console.WriteLine(b.M());
        }
    }

    class A
    {
        public A M()
        {
            return (A)Activator.CreateInstance(GetType());
        }
    }

    class B : A 
    {
    }
}

打印:

Test.A
Test.B 

答案 2 :(得分:0)

你所说的是基本工厂方法/模式。它有点偏离,因为创建自己的实例很奇怪。

但是可以肯定的是,你可以这样写:

class A
{
   public virtual A Create()
   {
      return new A();
   }
}

class B
{
   public override A Create()
   {
       return new B();
   }
}

当然,返回类型必须保留为基类,但由于您正在利用多态性,因此不应该成为问题。

通常,工厂方法将在另一个专用类中,只是你知道。

答案 3 :(得分:0)

是和否。考虑:

public class Parent
    {
        public int MyProperty { get; set; }

        public virtual Parent MyMethod()
        {
            return new Parent();
        }
    }

    public class A : Parent
    {
        public override Parent MyMethod()
        {
            return new A();
        }
    }

在A中,虽然返回类型是Parent,但您将返回A。

答案 4 :(得分:0)

如果您询问编译时间,则不能使用不同的返回类型编写覆盖方法。

但是在运行时是的,你可以,你将拥有这些类型的实例,但你必须编写你的代码,以便返回类型为&#39; A&#39;然后将它们转换为想要的类型。

相关问题