繁体   English   中英

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

[英]Return type of child class from parent class method

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

所以如果我做A.myMethod() ,我会得到一个A ,如果我做B.myMethod() ,我会得到一个B的实例?

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

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

最简单的方法是覆盖方法,使用new关键字隐藏原来的方法,让你改变签名。

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

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

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

第二种方法称为Static Polymorphism ,如果您使用某种工厂,它非常有用,但可能非常棘手,因为它只允许一个级别的实际继承。 静态多态类型以具有约束自身的泛型组件的类型开始:

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

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

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

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 

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

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

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

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

当然,返回类型必须保留为基类,但是由于您利用了多态性,这应该不是问题。

通常工厂方法会在另一个专门构建的类中,所以你知道。

是和否。考虑:

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。

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

但是在运行时是的,您可以并且您将拥有这些类型的实例,但是您必须编写代码以便具有“A”的返回类型,然后将它们转换为想要的类型。

暂无
暂无

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

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