How to Inherit method but with different return type?

前端 未结 10 986
北荒
北荒 2021-01-17 19:20

Given the following classes:

ClassA
{
     public ClassA DoSomethingAndReturnNewObject()
     {}    
}

ClassB : ClassA
{}

ClassC : ClassA
{}
相关标签:
10条回答
  • 2021-01-17 19:21

    Well, the correct answer is no and, generally, this is a bad idea. If you are returning something completely different, find another way.

    However, if you aren't returning something completely different, an interface can solve your issue. Instead of returning a class, return an interface and have classes A, B, and C return objects that implement that interface in the way they see fit.

    0 讨论(0)
  • 2021-01-17 19:21

    I finally devised the following solution. For my case it's useful enough, but it assumes that ClassA knows about it's derivatives and is limited to those two options. Not really high-level thinking, but it works. :)

    ClassA
    {
        public ClassA DoSomethingAndReturnNewObject()
        {
            if (this.GetType() == typeOf(ClassB))
            {
                return new ClassB(values);
            }
            else
            {
                return new ClassC(values):
            }
        }    
    }
    
    ClassB : ClassA
    {}
    
    ClassC : ClassA
    {}
    
    0 讨论(0)
  • 2021-01-17 19:25

    What you're describing is a covariant return type and is not supported in C#.

    However, you could create ClassA as an open generic and have the closed generic inheritors return their own type.

    Example:

    public abstract class ClassA<T> where T: ClassA<T>, new()
    {
        public abstract T DoSomethingAndReturnNewObject();
    }
    
    public class ClassB: ClassA<ClassB>
    {
        public override ClassB DoSomethingAndReturnNewObject()
        {
            //do whatever
        }
    }
    
    0 讨论(0)
  • 2021-01-17 19:26

    You need to create a protected virtual method for the DoSomethingAndReturnNewObject to use:

    class ClassA
    {
        protected virtual ClassA Create()
        {
            return new ClassA()
        }
    
        public ClassA DoSomethingAndReturnNewObject()
        {
            ClassA result = Create();
            // Do stuff to result
            return result;
        }
    }
    
    class ClassB : ClassA
    {
         protected override ClassA Create() { return new ClassB(); }
    }
    
    class ClassC : ClassA
    {
         protected override ClassA Create() { return new ClassC(); }
    }
    

    Note the return type remains ClassA but the object instance type will be the specific class.

    0 讨论(0)
  • 2021-01-17 19:28

    Maybe generics will be your saviour. Take a look at this link: C# Generics Part 3/4: Casting, Inheritance, and Generic Methods

    bstract class  B<T> {
       public abstract T Fct(T t);
    }
    class D1 : B<string>{
       public override string Fct( string t ) { return "hello"; }
    }
    class D2<T> : B<T>{
       public override T Fct(T t) { return default (T); }
    }
    
    0 讨论(0)
  • 2021-01-17 19:38
    class ClassA<T> where T : ClassA<T>, new()
    {
        public T DoSomethingAndReturnNewObject()
        {
            return new T();
        }
    }
    
    class ClassB : ClassA<ClassB> { }
    
    class ClassC : ClassA<ClassC> { }
    

    Test:

    ClassB b1 = new ClassB();
    
    ClassB b2 = b1.DoSomethingAndReturnNewObject(); // returns instance of ClassB
    
    0 讨论(0)
提交回复
热议问题