Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Override virtual or abstracts with derived return types

Override virtual or abstracts with derived return types

Scheduled Pinned Locked Moved C#
csharpquestion
11 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jofli
    wrote on last edited by
    #1

    Hi all, maybe someone can explain me, why this doesn't work in C#. Do i missed something, or is it a stupid idea to extend a return type of an override?

    public class Class_a
    {
    Stream _something;

        public virtual Stream Property
        {
            get
            {
                return \_something; 
            }
            set
            {
                \_something = value; 
            }
        }
    }
    
    public class Class\_b : Class\_a
    {
        FileStream \_something;
        
        public override FileStream Property
        {
            get
            {
                return \_something;
            }
            set
            {
                \_something = value;
            }
        }
    }
    

    Thanks & Regards, Johannes

    R J 3 Replies Last reply
    0
    • J jofli

      Hi all, maybe someone can explain me, why this doesn't work in C#. Do i missed something, or is it a stupid idea to extend a return type of an override?

      public class Class_a
      {
      Stream _something;

          public virtual Stream Property
          {
              get
              {
                  return \_something; 
              }
              set
              {
                  \_something = value; 
              }
          }
      }
      
      public class Class\_b : Class\_a
      {
          FileStream \_something;
          
          public override FileStream Property
          {
              get
              {
                  return \_something;
              }
              set
              {
                  \_something = value;
              }
          }
      }
      

      Thanks & Regards, Johannes

      R Offline
      R Offline
      Rahul RK
      wrote on last edited by
      #2

      Hello, You are trying to override the property 'Property' in derived class and you are trying to change the return type of the property, which is not allowed in the C#. In C#.Net it is mandatory to keep the signature of method/property you want to override in the derived class. Thanks, Rahul Kulkarni

      J 1 Reply Last reply
      0
      • J jofli

        Hi all, maybe someone can explain me, why this doesn't work in C#. Do i missed something, or is it a stupid idea to extend a return type of an override?

        public class Class_a
        {
        Stream _something;

            public virtual Stream Property
            {
                get
                {
                    return \_something; 
                }
                set
                {
                    \_something = value; 
                }
            }
        }
        
        public class Class\_b : Class\_a
        {
            FileStream \_something;
            
            public override FileStream Property
            {
                get
                {
                    return \_something;
                }
                set
                {
                    \_something = value;
                }
            }
        }
        

        Thanks & Regards, Johannes

        J Offline
        J Offline
        J4amieC
        wrote on last edited by
        #3

        As explained, its not possible but its not such a stupid idea. Ive tried a similar thing once or twice and found frustration.

        J 1 Reply Last reply
        0
        • J J4amieC

          As explained, its not possible but its not such a stupid idea. Ive tried a similar thing once or twice and found frustration.

          J Offline
          J Offline
          jofli
          wrote on last edited by
          #4

          Have you found any elegant solution for this?

          J 1 Reply Last reply
          0
          • R Rahul RK

            Hello, You are trying to override the property 'Property' in derived class and you are trying to change the return type of the property, which is not allowed in the C#. In C#.Net it is mandatory to keep the signature of method/property you want to override in the derived class. Thanks, Rahul Kulkarni

            J Offline
            J Offline
            jofli
            wrote on last edited by
            #5

            Hi Rahul, thanks! I understand that i'm not allowed to change the return type. But i thought it should be allowed to extend it. So from the perspective of 'Class_a' the return type will always be "Stream". I know that i could use 'new' instead of 'override', but that wouldn't be the same and won't work with abstracts. This rule doesn't make sense to me. regards, Johannes

            1 Reply Last reply
            0
            • J jofli

              Have you found any elegant solution for this?

              J Offline
              J Offline
              J4amieC
              wrote on last edited by
              #6

              Well in your example, even if you return a FileStream from a method whose return type is Stream the calling code can cast it to its actual type (FileStream). However this is, like most things, an architectural question where a different approach altogether is usually the most elegant solution. edit: Generics can sometime help here example coming....

              J 1 Reply Last reply
              0
              • J jofli

                Hi all, maybe someone can explain me, why this doesn't work in C#. Do i missed something, or is it a stupid idea to extend a return type of an override?

                public class Class_a
                {
                Stream _something;

                    public virtual Stream Property
                    {
                        get
                        {
                            return \_something; 
                        }
                        set
                        {
                            \_something = value; 
                        }
                    }
                }
                
                public class Class\_b : Class\_a
                {
                    FileStream \_something;
                    
                    public override FileStream Property
                    {
                        get
                        {
                            return \_something;
                        }
                        set
                        {
                            \_something = value;
                        }
                    }
                }
                

                Thanks & Regards, Johannes

                J Offline
                J Offline
                J4amieC
                wrote on last edited by
                #7

                Here's an elegant generics solution to your problem

                public class StreamWrapper<T> where T : Stream
                {
                private T stream;

                public T Stream
                {
                    get { return this.stream; }
                    set { this.stream = value; }
                }
                

                }

                public class FileStreamWrapper : StreamWrapper<FileStream>
                {
                public FileStreamWrapper()
                { }
                }

                When you instantiate FileStreamWrapper, its Stream property is correctly typed as FileStream.

                FileStreamWrapper fsw = new FileStreamWrapper();
                fsw.Stream = new FileStream(...);

                C 1 Reply Last reply
                0
                • J J4amieC

                  Well in your example, even if you return a FileStream from a method whose return type is Stream the calling code can cast it to its actual type (FileStream). However this is, like most things, an architectural question where a different approach altogether is usually the most elegant solution. edit: Generics can sometime help here example coming....

                  J Offline
                  J Offline
                  jofli
                  wrote on last edited by
                  #8

                  I'm facing this problem in several situations and i'm pretty sure this is an architectural question. This would be a good sample: There is a mask with a persons list and some search fields. I have a ViewModel class which provides the data (List) and the filter object (PersonFilter) where the search fields are bound to (WPF). Later i want to build a customers mask. Where the Customer class is an extension of Person and the CustomerFilter an extension PersonFilter. So i would love to extend my ViewModel, but i cannot override my Filter Property. Even if i'm sure that there won't be a solution, which let me do it this way. I thought it is time time to ask here. Thanks and regards, Johannes

                  1 Reply Last reply
                  0
                  • J J4amieC

                    Here's an elegant generics solution to your problem

                    public class StreamWrapper<T> where T : Stream
                    {
                    private T stream;

                    public T Stream
                    {
                        get { return this.stream; }
                        set { this.stream = value; }
                    }
                    

                    }

                    public class FileStreamWrapper : StreamWrapper<FileStream>
                    {
                    public FileStreamWrapper()
                    { }
                    }

                    When you instantiate FileStreamWrapper, its Stream property is correctly typed as FileStream.

                    FileStreamWrapper fsw = new FileStreamWrapper();
                    fsw.Stream = new FileStream(...);

                    C Offline
                    C Offline
                    carbon_golem
                    wrote on last edited by
                    #9

                    While your solution if FAR better, the OP could also declare the property as new instead of override. public class Class_a { public virtual Stream Property { get; set; } } public class Class_b : Class_a { public new FileStream Property { get; set; } }

                    "Simplicity carried to the extreme becomes elegance."
                    -Jon Franklin

                    B 1 Reply Last reply
                    0
                    • C carbon_golem

                      While your solution if FAR better, the OP could also declare the property as new instead of override. public class Class_a { public virtual Stream Property { get; set; } } public class Class_b : Class_a { public new FileStream Property { get; set; } }

                      "Simplicity carried to the extreme becomes elegance."
                      -Jon Franklin

                      B Offline
                      B Offline
                      Ben Fair
                      wrote on last edited by
                      #10

                      The easiest way to deal with this is to keep the type declaration of the base class property and cast to the actual type when working with the derived class. You can also consider whether you're going to need any of the functionality specific to FileStream. If Stream has all the functionality you need, then don't even worry about casting. I believe you may be able to do this with an Interface if you explicityly implement the interface item. Here's an example that works, but there's some trickery with an interface where you can have an explicit implementation of the interface defined that accesses the base class property and then a normal property of the same name that provides a different return type. Note that I had to implement the interface in both classes and also in Class_b I had to specifically cast to and from the different stream types. This is because even though Class_a implements the interface, I want to provide an explicit implementation in Class_b, so I have to implement it also in Class_b to do this. When you run this, Class_b.Property returns type FileStream while Class_a.Property returns type Stream.

                      using System;
                      using System.Collections.Generic;
                      using System.Text;
                      using System.IO;

                      namespace TestClass_a
                      {
                      public interface IStream
                      {
                      Stream Property { get; set; }
                      }

                      public class Class\_a : IStream
                      {
                          private Stream \_stream = null;
                      
                          public Stream Property
                          {
                              get { return \_stream; }
                              set { \_stream = value; }
                          }
                      }
                      
                      public class Class\_b : Class\_a, IStream
                      {
                          public FileStream Property
                          {
                              get { return (FileStream)base.Property; }
                              set { base.Property = (Stream)value; }
                          }
                      
                          #region IStream Members
                      
                          Stream IStream.Property
                          {
                              get { return base.Property; }
                              set { base.Property = value; }
                          }
                      
                          #endregion
                      }
                      
                      class Program
                      {
                          static void Main(string\[\] args)
                          {
                              Class\_a a = new Class\_a();
                              a.Property = new MemoryStream();
                              Class\_b b = new Class\_b();
                              b.Property = File.Open("C:\\\\test.txt", FileMode.OpenOrCreate);
                              Class\_a b2 = b;
                              bool canRead = b2.Property.CanRead;
                          }
                      }
                      

                      }

                      Keep It Simple Stupid! (KIS

                      J 1 Reply Last reply
                      0
                      • B Ben Fair

                        The easiest way to deal with this is to keep the type declaration of the base class property and cast to the actual type when working with the derived class. You can also consider whether you're going to need any of the functionality specific to FileStream. If Stream has all the functionality you need, then don't even worry about casting. I believe you may be able to do this with an Interface if you explicityly implement the interface item. Here's an example that works, but there's some trickery with an interface where you can have an explicit implementation of the interface defined that accesses the base class property and then a normal property of the same name that provides a different return type. Note that I had to implement the interface in both classes and also in Class_b I had to specifically cast to and from the different stream types. This is because even though Class_a implements the interface, I want to provide an explicit implementation in Class_b, so I have to implement it also in Class_b to do this. When you run this, Class_b.Property returns type FileStream while Class_a.Property returns type Stream.

                        using System;
                        using System.Collections.Generic;
                        using System.Text;
                        using System.IO;

                        namespace TestClass_a
                        {
                        public interface IStream
                        {
                        Stream Property { get; set; }
                        }

                        public class Class\_a : IStream
                        {
                            private Stream \_stream = null;
                        
                            public Stream Property
                            {
                                get { return \_stream; }
                                set { \_stream = value; }
                            }
                        }
                        
                        public class Class\_b : Class\_a, IStream
                        {
                            public FileStream Property
                            {
                                get { return (FileStream)base.Property; }
                                set { base.Property = (Stream)value; }
                            }
                        
                            #region IStream Members
                        
                            Stream IStream.Property
                            {
                                get { return base.Property; }
                                set { base.Property = value; }
                            }
                        
                            #endregion
                        }
                        
                        class Program
                        {
                            static void Main(string\[\] args)
                            {
                                Class\_a a = new Class\_a();
                                a.Property = new MemoryStream();
                                Class\_b b = new Class\_b();
                                b.Property = File.Open("C:\\\\test.txt", FileMode.OpenOrCreate);
                                Class\_a b2 = b;
                                bool canRead = b2.Property.CanRead;
                            }
                        }
                        

                        }

                        Keep It Simple Stupid! (KIS

                        J Offline
                        J Offline
                        jofli
                        wrote on last edited by
                        #11

                        I like this solution! Even if i tried to avoid doing a cast, this one seems elegant to me. Thank You for that. But i'm still curious why this (OP) is not allowed ...

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups