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. What about the other use of generic base class und generic polymorphism ?

What about the other use of generic base class und generic polymorphism ?

Scheduled Pinned Locked Moved C#
oopquestion
8 Posts 3 Posters 1 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.
  • M Offline
    M Offline
    MarkPhB
    wrote on last edited by
    #1

    What about this use of generic base class und generic polymorphism ? I found on the internet some Articles wich deal with generic base class and polymorphism but not in the following way. I know its not possible at the momenten but it should, i think. Lets say we have class declarations like this

    public class Range<T> {
        public T Start { get; set; }
        public T End { get; set; }
    }
    
    public class IntRange : Range<Int32> { }
    
    public class DoubleRange : Range<Double> { }
    
    public class DateTimeRange : Range<DateTime> { }
    

    then we could use it in this way

    Range<> range = new Range();
    range = new IntRange();
    
    range = new DoubleRange();
    

    and so far the T contrain is naked then the compiler should assume the Property are from Type Object.

    range = new IntRange();
    
    object obj = range.Start; // should compile
    
    int obj = range.Start; // don't compile
    
    int obj = (int) range.Start; // should compile
    

    or the T contrain is limited to a inheritance of ValueType.

    public class Range<T> where T : ValueType {
        public T Start { get; set; }
        public T End { get; set; }
    }
    
    ...
    
    range = new IntRange();
    
    int obj = range.Start; // should compile
    

    So i think that should be possible, or what you think ?

    C M 2 Replies Last reply
    0
    • M MarkPhB

      What about this use of generic base class und generic polymorphism ? I found on the internet some Articles wich deal with generic base class and polymorphism but not in the following way. I know its not possible at the momenten but it should, i think. Lets say we have class declarations like this

      public class Range<T> {
          public T Start { get; set; }
          public T End { get; set; }
      }
      
      public class IntRange : Range<Int32> { }
      
      public class DoubleRange : Range<Double> { }
      
      public class DateTimeRange : Range<DateTime> { }
      

      then we could use it in this way

      Range<> range = new Range();
      range = new IntRange();
      
      range = new DoubleRange();
      

      and so far the T contrain is naked then the compiler should assume the Property are from Type Object.

      range = new IntRange();
      
      object obj = range.Start; // should compile
      
      int obj = range.Start; // don't compile
      
      int obj = (int) range.Start; // should compile
      

      or the T contrain is limited to a inheritance of ValueType.

      public class Range<T> where T : ValueType {
          public T Start { get; set; }
          public T End { get; set; }
      }
      
      ...
      
      range = new IntRange();
      
      int obj = range.Start; // should compile
      

      So i think that should be possible, or what you think ?

      C Offline
      C Offline
      Christian Graus
      wrote on last edited by
      #2

      Anything that puts us back in the world of essentially containers that are not type safe, is bad IMO. You may as well create a collection of arraylists, if you're going to cast them anyhow

      Christian Graus Please read this if you don't understand the answer I've given you. If you're still stuck, ask me for more information.

      1 Reply Last reply
      0
      • M MarkPhB

        What about this use of generic base class und generic polymorphism ? I found on the internet some Articles wich deal with generic base class and polymorphism but not in the following way. I know its not possible at the momenten but it should, i think. Lets say we have class declarations like this

        public class Range<T> {
            public T Start { get; set; }
            public T End { get; set; }
        }
        
        public class IntRange : Range<Int32> { }
        
        public class DoubleRange : Range<Double> { }
        
        public class DateTimeRange : Range<DateTime> { }
        

        then we could use it in this way

        Range<> range = new Range();
        range = new IntRange();
        
        range = new DoubleRange();
        

        and so far the T contrain is naked then the compiler should assume the Property are from Type Object.

        range = new IntRange();
        
        object obj = range.Start; // should compile
        
        int obj = range.Start; // don't compile
        
        int obj = (int) range.Start; // should compile
        

        or the T contrain is limited to a inheritance of ValueType.

        public class Range<T> where T : ValueType {
            public T Start { get; set; }
            public T End { get; set; }
        }
        
        ...
        
        range = new IntRange();
        
        int obj = range.Start; // should compile
        

        So i think that should be possible, or what you think ?

        M Offline
        M Offline
        Mark Churchill
        wrote on last edited by
        #3

        No, its not possible. Range< int > and Range< float > are two completely seperate types. I went through the basic reasoning in ( http://www.codeproject.com/script/Forums/View.aspx?fid=1649&msg=2612653 ) that thread. If you do want them to inherit from a common base then make it explicit: class Range< t > : BaseRange. I think you might be a little confused when you inherit IntRange : Range< int > - you would only need to do this if you were adding extra int specific functionality. Edit: Damn, need to remember to add spaces for < and >

        Mark Churchill Director Dunn & Churchill Free Download:
        Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.

        modified on Saturday, June 28, 2008 11:31 PM

        M 1 Reply Last reply
        0
        • M Mark Churchill

          No, its not possible. Range< int > and Range< float > are two completely seperate types. I went through the basic reasoning in ( http://www.codeproject.com/script/Forums/View.aspx?fid=1649&msg=2612653 ) that thread. If you do want them to inherit from a common base then make it explicit: class Range< t > : BaseRange. I think you might be a little confused when you inherit IntRange : Range< int > - you would only need to do this if you were adding extra int specific functionality. Edit: Damn, need to remember to add spaces for < and >

          Mark Churchill Director Dunn & Churchill Free Download:
          Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.

          modified on Saturday, June 28, 2008 11:31 PM

          M Offline
          M Offline
          MarkPhB
          wrote on last edited by
          #4

          Mark Churchill wrote:

          No, its not possible.

          that's right, its not possible, but it should be, in my opinion. :)

          Mark Churchill wrote:

          Range< int > and Range< float > are two completely seperate types.

          that's right as well, that's why IMO there should be a posibility to use generic classes as basis.

          List<> list = new List<>(); // T should be assumed as Object or as the type limited through the where contrain
          

          By the way i forgot to declare the Range<T> class as abstract. Its just a base class and must be inherited because we can not implement some methods, for example IsBetween(T value);

          Range<> range = Range<>();
          range.Start // <- from type object
          range.End// <- from type object
          
          range = new IntRange();
          range.Start // <- from type int
          range.End// <- from type int
          
          range = new DoubleRange();
          range.Start // <- from type double
          range.End// <- from type double
          

          Mark Churchill wrote:

          class Range< t > : BaseRange.

          What would that bring? :^) The property Start and End would be ever from the type Object and can't take another type, except we override them with new.

          M 1 Reply Last reply
          0
          • M MarkPhB

            Mark Churchill wrote:

            No, its not possible.

            that's right, its not possible, but it should be, in my opinion. :)

            Mark Churchill wrote:

            Range< int > and Range< float > are two completely seperate types.

            that's right as well, that's why IMO there should be a posibility to use generic classes as basis.

            List<> list = new List<>(); // T should be assumed as Object or as the type limited through the where contrain
            

            By the way i forgot to declare the Range<T> class as abstract. Its just a base class and must be inherited because we can not implement some methods, for example IsBetween(T value);

            Range<> range = Range<>();
            range.Start // <- from type object
            range.End// <- from type object
            
            range = new IntRange();
            range.Start // <- from type int
            range.End// <- from type int
            
            range = new DoubleRange();
            range.Start // <- from type double
            range.End// <- from type double
            

            Mark Churchill wrote:

            class Range< t > : BaseRange.

            What would that bring? :^) The property Start and End would be ever from the type Object and can't take another type, except we override them with new.

            M Offline
            M Offline
            Mark Churchill
            wrote on last edited by
            #5

            I'm not sure where the percieved benefit of having a concrete IntRange deriving from a Range< T >. Generics are specialization, not inheritance. Sometimes covariance/contravariance (always forget which way those go) is appropriate, but it generally leads to breaking type safety. As generics are generally used to provide type safety then you would be defeating one of their main purposes. I would suggest the correct way of implementing and using a generic Range class would be along the lines of:

            class Range< T > where T : IComparable< T >
            {
            T Start;
            T End;
            bool IsBetween(T i) => Start.CompareTo(i) < 0 && End.CompareTo(i) > 0;
            }

            Then the usage is trivial. No need for an abstract generic class with concrete types.

            Mark Churchill Director Dunn & Churchill Free Download:
            Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.

            M 1 Reply Last reply
            0
            • M Mark Churchill

              I'm not sure where the percieved benefit of having a concrete IntRange deriving from a Range< T >. Generics are specialization, not inheritance. Sometimes covariance/contravariance (always forget which way those go) is appropriate, but it generally leads to breaking type safety. As generics are generally used to provide type safety then you would be defeating one of their main purposes. I would suggest the correct way of implementing and using a generic Range class would be along the lines of:

              class Range< T > where T : IComparable< T >
              {
              T Start;
              T End;
              bool IsBetween(T i) => Start.CompareTo(i) < 0 && End.CompareTo(i) > 0;
              }

              Then the usage is trivial. No need for an abstract generic class with concrete types.

              Mark Churchill Director Dunn & Churchill Free Download:
              Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.

              M Offline
              M Offline
              MarkPhB
              wrote on last edited by
              #6

              yea, i didn't tought about that way :) thx but what if, i have a class wich contain a range that can be a range of DateTime and a range of ULong. In that case i must use the object type as basis :^) Class SomeClassName{ public **object** RangeProperty{get; set; } public SomeClassName( object range ){ RangeProperty = range; } public DataTable SearchForDatabaseEntries(){ if( RangeProperty is Range<DateTime> ){ // Range can be used to search for entries with DateTime info ( for example: CreationTime ) } else if( RangeProperty is Range<ULong> ){ // Range can be used to search for entries with Numeric info ( for example: SerialNumber ) } ... } } Do you understand my intension now ? :)

              M 1 Reply Last reply
              0
              • M MarkPhB

                yea, i didn't tought about that way :) thx but what if, i have a class wich contain a range that can be a range of DateTime and a range of ULong. In that case i must use the object type as basis :^) Class SomeClassName{ public **object** RangeProperty{get; set; } public SomeClassName( object range ){ RangeProperty = range; } public DataTable SearchForDatabaseEntries(){ if( RangeProperty is Range<DateTime> ){ // Range can be used to search for entries with DateTime info ( for example: CreationTime ) } else if( RangeProperty is Range<ULong> ){ // Range can be used to search for entries with Numeric info ( for example: SerialNumber ) } ... } } Do you understand my intension now ? :)

                M Offline
                M Offline
                Mark Churchill
                wrote on last edited by
                #7

                Yep, in that case you are going to end up with casting anyway. I'd treat the Range class as a structure, like Point. Anything that does any "work" should probably accept a Range class as a parameter - theres just too many potential uses for Range to make every usage scenario a member function. As long as you have say "IsBetween", "IsNotBetween" matching the Predicate< T > delegate then it should be useful enough. If you are dealing with DataTables then you are dealing with objects, casting and constant invalidcastexceptions anyway, so I wouldnt worry too much ;)

                Mark Churchill Director Dunn & Churchill Free Download:
                Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.

                M 1 Reply Last reply
                0
                • M Mark Churchill

                  Yep, in that case you are going to end up with casting anyway. I'd treat the Range class as a structure, like Point. Anything that does any "work" should probably accept a Range class as a parameter - theres just too many potential uses for Range to make every usage scenario a member function. As long as you have say "IsBetween", "IsNotBetween" matching the Predicate< T > delegate then it should be useful enough. If you are dealing with DataTables then you are dealing with objects, casting and constant invalidcastexceptions anyway, so I wouldnt worry too much ;)

                  Mark Churchill Director Dunn & Churchill Free Download:
                  Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.

                  M Offline
                  M Offline
                  MarkPhB
                  wrote on last edited by
                  #8

                  Mark Churchill wrote:

                  If you are dealing with DataTables then you are dealing with objects, casting and constant invalidcastexceptions anyway, so I wouldnt worry too much [Wink]

                  Not quite :) i use the range-class to built a sqlstatement and to determine whether i have to ask a Id-Colum or a DateTime-Column from a table ;)

                  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