简体   繁体   English

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

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

If I have a class A , and classes B , C , and D that inherit from A , is there a way to write a method in A that, when called on the subclass, will have a return type of the subclass?如果我有一个类A以及从A继承的类BCD ,有没有办法在A中编写一个方法,当在子类上调用时,该方法将具有子类的返回类型?

So if I were to do A.myMethod() , I would get an A , and if I were to do B.myMethod() , I would get an instance of B ?所以如果我做A.myMethod() ,我会得到一个A ,如果我做B.myMethod() ,我会得到一个B的实例?

What you are asking is not strictly polymorphism, since you want to override a return type, and thus have a different signature from the original method.您要问的不是严格的多态性,因为您要覆盖返回类型,因此具有与原始方法不同的签名。 True polymorphism changes none of this signature, so what you're asking isn't a first-class situation in C#.真正的多态不会改变这个签名,所以你问的不是 C# 中的一流情况。

That being said, there are at least two ways about it.话虽如此,至少有两种方法。

The simplest way is to override the method, using the new keyword to hide the original method, allowing you to change the signature.最简单的方法是覆盖方法,使用new关键字隐藏原来的方法,让你改变签名。

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

This will allow any usages of B to return a B , but does not actually override the behaviour of A.MyMethod .这将允许B任何用法返回B ,但实际上不会覆盖A.MyMethod的行为。 It can be useful to avoid repetitive typecasting in code.避免代码中的重复类型转换很有用。

if you need to also override the method to allow it to return an object of type B , this cannot coexist in the same class, because the compiler sees the same signature (same name, same parameters, even though the return type is explcitly different).如果您还需要覆盖该方法以允许它返回类型B的对象,则这不能共存于同一个类中,因为编译器看到相同的签名(相同的名称,相同的参数,即使返回类型显式不同) .

The second way is called Static Polymorphism , and is very useful if you're using a factory of some kind, but can bevery tricky to work around, because it allows exactly one level of actual inheritance.第二种方法称为Static Polymorphism ,如果您使用某种工厂,它非常有用,但可能非常棘手,因为它只允许一个级别的实际继承。 A Statically Polymorphic type starts with a type that has a Generic component constrained against itself:静态多态类型以具有约束自身的泛型组件的类型开始:

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

This means your method could return an object of type TSelf or even make this an abstract method so each inheritor has to deal with the constructor, but any class inherited from B has a harder time overriding this, since it's inheriting from A<B> , not A<C>这意味着你的方法可以返回一个TSelf类型的对象,甚至使它成为一个抽象方法,所以每个继承者都必须处理构造函数,但是从B继承的任何类都很难覆盖它,因为它是从A<B>继承的,不是A<C>

Assuming that you want to declare method myMethod in A only, you can do the following:假设您只想在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 
    {
    }
}

prints:印刷:

Test.A
Test.B 

What you are talking about is basically a Factory method/pattern.您所谈论的基本上是工厂方法/模式。 Its a little off because instances creating themselves is just weird.它有点偏离,因为创建自己的实例很奇怪。

But sure, you can write this:但可以肯定的是,你可以这样写:

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

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

Of course, the return type has to stay as the base class, but since you are taking advantage of polymorphism, that shouldn't be a problem.当然,返回类型必须保留为基类,但是由于您利用了多态性,这应该不是问题。

Normally the factory method would be in another purpose-built class, just so you know.通常工厂方法会在另一个专门构建的类中,所以你知道。

Yes and No. Consider:是和否。考虑:

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

In A, although the return type is Parent, you are returning an A.在 A 中,虽然返回类型是 Parent,但您返回的是 A。

If you asking about compile time no you can't write override methods with different return types.如果您询问编译时间,则不能编写具有不同返回类型的覆盖方法。

But on run time yes you can and you will have those type of instances but you have to write your code so as to have a return type of 'A' and then cast them to wanted type.但是在运行时是的,您可以并且您将拥有这些类型的实例,但是您必须编写代码以便具有“A”的返回类型,然后将它们转换为想要的类型。

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

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