How to return subtype in overridden method of subclass in C#?

前端 未结 7 1834
北海茫月
北海茫月 2020-12-09 14:59

I have a subclass with an over-ridden method that I know always returns a particular subtype of the return type declared in the base class. If I write the code this way, it

相关标签:
7条回答
  • 2020-12-09 15:33

    Change your method signature on Derived class to:

     public override BaseReturnType PolymorphicMethod() 
     {
        return new DerivedReturnType();     
     }
    

    C# doesn't support variant return types. You can check out this post for a way to do this using Generics...http://srtsolutions.com/blogs/billwagner/archive/2005/06/17/covaraint-return-types-in-c.aspx

    Here's a sample using Generics in your model:

    public class BaseReturnType
    {
    }
    public class DerivedReturnType : BaseReturnType
    {
    }
    
    public abstract class BaseClass<T> where T : BaseReturnType
    {
        public abstract T PolymorphicMethod();
    
    }
    
    public class DerviedClass : BaseClass<DerivedReturnType>
    {
        public override DerivedReturnType PolymorphicMethod()
        {
            throw new NotImplementedException();
        }
    }
    
    0 讨论(0)
  • 2020-12-09 15:38

    It seems to me that you need to be returning an interface, not a base class.

    0 讨论(0)
  • 2020-12-09 15:41
    class BaseReturnType { }
    class DerivedReturnType : BaseReturnType { }
    
    abstract class BaseClass {
        public abstract BaseReturnType PolymorphicMethod();
    }
    
    class DerivedClass : BaseClass {
        // Error: return type must be 'BaseReturnType' to match 
        // overridden member 'BaseClass.PolymorphicMethod()'
        public override BaseReturnType PolymorphicMethod() { 
            return new DerivedReturnType(); 
        }
    }
    

    this should work

    0 讨论(0)
  • 2020-12-09 15:43

    You could make the class generic if that doesn't bothers you:

        class BaseReturnType { }
        class DerivedReturnType : BaseReturnType { }
    
        abstract class BaseClass<T> where T : BaseReturnType
        {
            public abstract T PolymorphicMethod();
        }
    
        class DerivedClass : BaseClass<DerivedReturnType>
        {
            // Error: return type must be 'BaseReturnType' to match 
            // overridden member 'BaseClass.PolymorphicMethod()'
            public override DerivedReturnType PolymorphicMethod()
            {
                return new DerivedReturnType();
            }
        }
    
    0 讨论(0)
  • 2020-12-09 15:49

    Generics are not necessarily the way to go. In particular, type(of Derived) is not considered a type(of Base).

    First, add a new method to your derived class which will return the value with the correct type. Second, mark the overriding method not-overridable and have it delegate to your new method.

    That's it. You've solved your problem. Child classes won't be able to re-expand the type because they must override your new method.

    I apologize if the code isn't quite right; I'm used to VB.net.

    abstract class C1 {
        public abstract IEnumerable<Byte> F1();
    }
    class C2 : C1 {
        public sealed override IEnumerable<Byte> F1() {
            Return F2();
        }
        public overridable IList<Byte> F2() {
            Return {1, 2, 3, 4};
        }
    }
    
    0 讨论(0)
  • 2020-12-09 15:52

    You can do this if you introduce an extra method to override (since you can't override and new a method with the same name in the same type):

    abstract class BaseClass
    {
        public BaseReturnType PolymorphicMethod()
        { return PolymorphicMethodCore();}
    
        protected abstract BaseReturnType PolymorphicMethodCore();
    }
    
    class DerivedClass : BaseClass
    {
        protected override BaseReturnType PolymorphicMethodCore()
        { return PolymorphicMethod(); }
    
        public new DerivedReturnType PolymorphicMethod()
        { return new DerivedReturnType(); }
    }
    

    Now you have a PolymorphicMethod method at each level with the correct type.

    0 讨论(0)
提交回复
热议问题