473,320 Members | 1,922 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

.NET 2.0 Generics and type casting

Hi,

I am trying to create a new generic class and am having trouble casting
a generic type to a specific type. For example,

public class MyClass<Twhere T : MyItemClass, new()
{
public MyClass() { }

public void AppendItem()
{
T myItem = new T();
myItem.Parent = this;
}

}

public class MyItemClass
{
public MyClass<MyItemClassParent;

public MyItemClass() { }
}

fails to compile with the error: Cannot implicitly convert type
'GenericInheritanceTst.MyClass<T>'
to 'GenericInheritanceTst.MyClass<GenericInheritanceT st.MyItem Class>'.

Has anyone seen this problem and found a resolution?

Thanks.
Kris
Jul 22 '06 #1
8 2390
"Kris Jennings" <no***@nowhere.comwrote:
I am trying to create a new generic class and am having trouble casting
a generic type to a specific type. For example,

public class MyClass<Twhere T : MyItemClass, new()
{
public MyClass() { }

public void AppendItem()
{
T myItem = new T();
myItem.Parent = this;
}
}

public class MyItemClass
{
public MyClass<MyItemClassParent;

public MyItemClass() { }
}
The root of the problem is that C# generics aren't covariant.

Imagine a subclass of MyItemClass (say MySubItemClass):

public class MySubItemClass : MyItemClass {}

Consider then that the type of MySubItemClass.Parent is still
MyClass<MyItemClass>, but a possible instantiation of MyClass<Tis
MyClass<MySubItemClass>. In this case (i.e. if MyClass<was
instantiated with the MySubItemClass), the AppendItem() method would be
trying to assign a MyClass<MySubItemClassto a field of type
MyClass<MyItemClass>.

That isn't allowed, because covariance isn't allowed by C# generics.

If A is a subclass of B, that does not mean that G<Ais a subclass of
G<B>, where G<is a generic type. Thus, instances of G<Baren't
assignment-compatible with locations of type G<A>.
Has anyone seen this problem and found a resolution?
You could make your item class generic. Consider this:

---8<---
using System;
using System.Collections.Generic;

class Program
{
class Container<T>
where T : Item<T>, new()
{
public List<TItems = new List<T>();

public void Append()
{
T item = new T();
item.Container = this;
Items.Add(item);
}
}

class Item<TBase>
where TBase : Item<TBase>, new()
{
public Container<TBaseContainer;
}

class SubItem : Item<SubItem>
{
}

static void Main()
{
Container<SubItemcontainer = new Container<SubItem>();
container.Append();
container.Items.ForEach(Console.WriteLine);
}
}
--->8---

-- Barry

--
http://barrkel.blogspot.com/
Jul 22 '06 #2
Barry,
So from that point:
class Container<T>
where T : Item<T>, new()

class Item<TBase>
where TBase : Item<TBase>, new()

You show:
Container<SubItemcontainer = new Container<SubItem>();

Is there no easy way from this point though to decalre a list of ANY kind of
item?
Container<Itemcontainer = new Container<Item>();
will not work because Item now requires template arguments.

--
Adam Clauss
"Barry Kelly" <ba***********@gmail.comwrote in message
news:9e********************************@4ax.com...
"Kris Jennings" <no***@nowhere.comwrote:
>I am trying to create a new generic class and am having trouble casting
a generic type to a specific type. For example,

public class MyClass<Twhere T : MyItemClass, new()
{
public MyClass() { }

public void AppendItem()
{
T myItem = new T();
myItem.Parent = this;
}
}

public class MyItemClass
{
public MyClass<MyItemClassParent;

public MyItemClass() { }
}

The root of the problem is that C# generics aren't covariant.

Imagine a subclass of MyItemClass (say MySubItemClass):

public class MySubItemClass : MyItemClass {}

Consider then that the type of MySubItemClass.Parent is still
MyClass<MyItemClass>, but a possible instantiation of MyClass<Tis
MyClass<MySubItemClass>. In this case (i.e. if MyClass<was
instantiated with the MySubItemClass), the AppendItem() method would be
trying to assign a MyClass<MySubItemClassto a field of type
MyClass<MyItemClass>.

That isn't allowed, because covariance isn't allowed by C# generics.

If A is a subclass of B, that does not mean that G<Ais a subclass of
G<B>, where G<is a generic type. Thus, instances of G<Baren't
assignment-compatible with locations of type G<A>.
>Has anyone seen this problem and found a resolution?

You could make your item class generic. Consider this:

---8<---
using System;
using System.Collections.Generic;

class Program
{
class Container<T>
where T : Item<T>, new()
{
public List<TItems = new List<T>();

public void Append()
{
T item = new T();
item.Container = this;
Items.Add(item);
}
}

class Item<TBase>
where TBase : Item<TBase>, new()
{
public Container<TBaseContainer;
}

class SubItem : Item<SubItem>
{
}

static void Main()
{
Container<SubItemcontainer = new Container<SubItem>();
container.Append();
container.Items.ForEach(Console.WriteLine);
}
}
--->8---

-- Barry

--
http://barrkel.blogspot.com/

Jul 24 '06 #3
Adam Clauss wrote:
Barry,
So from that point:
class Container<T>
where T : Item<T>, new()

class Item<TBase>
where TBase : Item<TBase>, new()

You show:
Container<SubItemcontainer = new Container<SubItem>();

Is there no easy way from this point though to decalre a list of ANY kind of
item?
Container<Itemcontainer = new Container<Item>();
will not work because Item now requires template arguments.
If there is some behavior which all Item<>s have in common - and this
must of course not depend on the type used to construct the Item<-
then put that behavior in an interface IItem to be implemented by
Item<>. Then you can have a Container<IItem>.

--
Larry Lard
la*******@googlemail.com
The address is real, but unread - please reply to the group
For VB and C# questions - tell us which version
Jul 24 '06 #4
"Adam Clauss" <ca*****@no.spam.gmail.comwrote:
Barry,
So from that point:
class Container<T>
where T : Item<T>, new()

class Item<TBase>
where TBase : Item<TBase>, new()

You show:
Container<SubItemcontainer = new Container<SubItem>();

Is there no easy way from this point though to decalre a list of ANY kind of
item?
You want your item to have a 'Container' reference. If you change Item
to be an interface (preferably with an 'I' prefix), you can do it with
interfaces instead.
Container<Itemcontainer = new Container<Item>();
will not work because Item now requires template arguments.
The whole point of Item is for you to descend from it.

-- Barry

--
http://barrkel.blogspot.com/
Jul 24 '06 #5


Hi All,

I would like to thank everyone for their response on this issue.

I was hoping to be able to do this is a fairly direct fashion. It seems
like a fundamental limitation of .NET generics that they don't support
inheritance of the generic types (as Barry indicated, "If A is a subclass
of B, that does not mean that G<Ais a subclass of G<B>, where
G<is a generic type".)

I really wanted to avoid changing class inheritance heirarchy to solve
a generics problem. My concern is that, while I may get a complete
understanding of this now, 6 months from now I will need to rethink all
of this again when debugging some problem. I feel these things like this
need to be implemented in a fairly straight-forward manner so as to minimize
difficulty with maintaining the code.

I wonder what the reasons are for such limitations.
Kris
"Barry Kelly" <ba***********@gmail.comwrote in message
news:6j********************************@4ax.com...
"Adam Clauss" <ca*****@no.spam.gmail.comwrote:
>Barry,
So from that point:
class Container<T>
where T : Item<T>, new()

class Item<TBase>
where TBase : Item<TBase>, new()

You show:
Container<SubItemcontainer = new Container<SubItem>();

Is there no easy way from this point though to decalre a list of ANY kind
of
item?

You want your item to have a 'Container' reference. If you change Item
to be an interface (preferably with an 'I' prefix), you can do it with
interfaces instead.
>Container<Itemcontainer = new Container<Item>();
will not work because Item now requires template arguments.

The whole point of Item is for you to descend from it.

-- Barry

--
http://barrkel.blogspot.com/

Jul 24 '06 #6
"Barry Kelly" <ba***********@gmail.comwrote in message
news:6j********************************@4ax.com...
"Adam Clauss" <ca*****@no.spam.gmail.comwrote:
You want your item to have a 'Container' reference. If you change Item
to be an interface (preferably with an 'I' prefix), you can do it with
interfaces instead.
Thanks to both Larry and Barry.
Could one of you (or both) see a thread above this one from Lars (dated
7/21/06, 3:31pm). My question here stemmed from our discussion there, and I
think I have gone past my knowledge at this point.
Thanks!

--
Adam Clauss
Jul 25 '06 #7
"Kris" <no****@dev.nullwrote:
I was hoping to be able to do this is a fairly direct fashion. It seems
like a fundamental limitation of .NET generics that they don't support
inheritance of the generic types (as Barry indicated, "If A is a subclass
of B, that does not mean that G<Ais a subclass of G<B>, where
G<is a generic type".)
..NET does support it. C# doesn't. It is limited, though. I wrote an
article on it on my blog (see my signature, look for covariance and
contravariance). Consider:

List<Mammalmammals = new List<Dog>();
mammals.Add(new Cat());

Taking this example into account, can you see the limitations of
supporting covariance with generics?
I really wanted to avoid changing class inheritance heirarchy to solve
a generics problem.
You don't need to change your class inheritance hierarchy - you can use
an interface instead.
I wonder what the reasons are for such limitations.
Generic types can support covariance and contravariance in limited
scenarios, depending on what operations are available on the types. For
more details, see my blog.

C# probably excluded them (at least for version 2.0) to avoid confusing
people with the limitations etc.

-- Barry

--
http://barrkel.blogspot.com/
Jul 25 '06 #8


Barry,

Your blog brings to light some interesting points. I can see how support
for covariance and contravariance invites misuse. Still, without this
type of support (I don't know if covariance and contravariance would both
be needed), there are many problems that seem to be very difficult, if not
impossible, to implement using generics, as inheritance is necessary in
many cases. I guess we get to see if Micosoft decides to support this for
C# in .NET 3.0.

Thanks for all of your help.
Kris
"Barry Kelly" <ba***********@gmail.comwrote in message
news:97********************************@4ax.com...
"Kris" <no****@dev.nullwrote:
>I was hoping to be able to do this is a fairly direct fashion. It seems
like a fundamental limitation of .NET generics that they don't support
inheritance of the generic types (as Barry indicated, "If A is a subclass
of B, that does not mean that G<Ais a subclass of G<B>, where
G<is a generic type".)

.NET does support it. C# doesn't. It is limited, though. I wrote an
article on it on my blog (see my signature, look for covariance and
contravariance). Consider:

List<Mammalmammals = new List<Dog>();
mammals.Add(new Cat());

Taking this example into account, can you see the limitations of
supporting covariance with generics?
>I really wanted to avoid changing class inheritance heirarchy to solve
a generics problem.

You don't need to change your class inheritance hierarchy - you can use
an interface instead.
>I wonder what the reasons are for such limitations.

Generic types can support covariance and contravariance in limited
scenarios, depending on what operations are available on the types. For
more details, see my blog.

C# probably excluded them (at least for version 2.0) to avoid confusing
people with the limitations etc.

-- Barry

--
http://barrkel.blogspot.com/

Jul 25 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: KC | last post by:
Could some one explain to me the casting rules for sending generic lists, ex. List<Person>, to a function that accepts List<object>? I cannot get the following easy-cheesy app to work. I get the...
7
by: Gene Vital | last post by:
Hi all, I need some help in understanding how to use Generics. I have a class based on a user control that can be put on any Container at runtime, I want to be able to call a method on the...
7
by: Ajeet | last post by:
hi I am having some difficulty in casting using generics. These are the classes. public interface IProvider<PROF> where PROF : IProviderProfile { //Some properties/methods }
3
by: psyCK0 | last post by:
Hi all! I have a problem of casting generics to their base type. In the code below I first define a BaseList class that can hold items of any type that inherits from BaseItem. I then define a...
13
by: rkausch | last post by:
Hello everyone, I'm writing because I'm frustrated with the implementation of C#'s generics, and need a workaround. I come from a Java background, and am currently writing a portion of an...
4
by: Random | last post by:
I want to define a generics method so the user can determine what type they expect returned from the method. By examining the generics argument, I would determine the operation that needs to be...
3
by: =?Utf-8?B?RnJhbmsgVXJheQ==?= | last post by:
Hi all I have some problems with Crystal Reports (Version 10.2, Runtime 2.0). In Section3 I have added a OLE Object (Bitmap). Now when I open the report in my code I would like to set this...
3
by: Anders Borum | last post by:
Hello, I've worked on an API for quite some time and have (on several occasions) tried to introduce generics at the core abstract level of business objects (especially a hierarchical node). The...
8
by: Tony Johansson | last post by:
Hello! I have read that in practice, casting proved to be several times faster than using a generic. So the main reason to use generics is not that the performance is better because that's...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.