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