473,396 Members | 1,779 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,396 software developers and data experts.

C#/2.0: Tricky issue with generics.

Ok, working my way through a complex library conversion to .NET 2.0 and C#
2.0 with generics I am totally stuck on one thing -if anyone sees the issue
I would be more than glad.

The situation is that we have a tree of "Node" objects. A Node is a
visualizable item, like a component. THe menues of all or ouf applications,
for example, are node hierarchies that an adapter transposes into a menu
model.

Now, Nodes have an internal DataObject, which can hold the actual data -
often a business object. This was so far a Object, now it will be T.

So, the definition of Node looks like this now:

public class Node<T> :
SmartObject,
INamed
where
T : class
{

The T is supposed to indicate the type of the DataObject, which can be any
class. There is a class NodeList that is basically a glorified IList with a
lot of additional functionality. It looks like this:

public class NodeList<T> :
ObjectBindingList<T>
where
T : Node<Object>
{

The idea is that a NodeList can hold any Node and should be strong-typable
for this. Now, here the issues come. A Node itself has a Collection
"Children". This is similar to the collection if children in the component
hierarchy. Nodes are not restricted to subtypes - and the constructor of the
NodeList can take a Node that is the parent. If there is a parent in a
NodeList, there is a lot of stuff going on when you add/remove thigs. So,
there is aconstructor like this:

public NodeList(Node<Object> Parent)

As you can see, ANY Node can be the parent.

And here the issues start. In the constructor of the Node I create the
ChildNodes:

_ChildNodes = new NodeList<Node<Object>> (this);

And the issue is: this blows. And I have no clue why. The error messages
are:

Error 2 The best overloaded method match for
'Foundation.Nodes.NodeList<Foundation.Nodes.Node<o bject>>.NodeList(Foundation.Nodes.Node<object>)'
has some invalid arguments
C:\WORK\ThonaConsulting\EntityBroker\03.0\Foundati on\Nodes\Node.cs 29 18
Foundation

Error 3 Argument '1': cannot convert from 'Foundation.Nodes.Node<T>' to
'Foundation.Nodes.Node<object>'
C:\WORK\ThonaConsulting\EntityBroker\03.0\Foundati on\Nodes\Node.cs 29 46
Foundation
Now, this I simply do not understand. The argument "this" is a Node<T> - and
is not convertible to Node<object>? Why not? T is supposed to be a class,
and object is the base-class of all classes. Also, I cano not even cast
this:

_ChildNodes = new NodeList<Node<Object>> ((Node<T>)this);

produces the exactly SAME error. I simply do not understand why. As I said,
the case should be totally valid in my optinion.

Anyone a clue? This starts to look like a compiler error to me, but I still
fear I just overlook something. I mean, this is created WITHIN A node, so
thi sshould be totally valid, or?

Thomas Tomiczek
Nov 17 '05 #1
6 1952
Thomas,

The reason for this is that with generics, if you have a class B, that
inherits from A, then C<B> does NOT inherit from C<A>. The same goes for
casting.

To get around this, you should have a non-generic interface which
exposes the functionality of your node, and pass that around to the
constructor of your node class.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"Thomas Tomiczek" <t.********@thona-consulting.com> wrote in message
news:uX**************@TK2MSFTNGP14.phx.gbl...
Ok, working my way through a complex library conversion to .NET 2.0 and C#
2.0 with generics I am totally stuck on one thing -if anyone sees the
issue I would be more than glad.

The situation is that we have a tree of "Node" objects. A Node is a
visualizable item, like a component. THe menues of all or ouf
applications, for example, are node hierarchies that an adapter transposes
into a menu model.

Now, Nodes have an internal DataObject, which can hold the actual data -
often a business object. This was so far a Object, now it will be T.

So, the definition of Node looks like this now:

public class Node<T> :
SmartObject,
INamed
where
T : class
{

The T is supposed to indicate the type of the DataObject, which can be any
class. There is a class NodeList that is basically a glorified IList with
a lot of additional functionality. It looks like this:

public class NodeList<T> :
ObjectBindingList<T>
where
T : Node<Object>
{

The idea is that a NodeList can hold any Node and should be strong-typable
for this. Now, here the issues come. A Node itself has a Collection
"Children". This is similar to the collection if children in the component
hierarchy. Nodes are not restricted to subtypes - and the constructor of
the NodeList can take a Node that is the parent. If there is a parent in a
NodeList, there is a lot of stuff going on when you add/remove thigs. So,
there is aconstructor like this:

public NodeList(Node<Object> Parent)

As you can see, ANY Node can be the parent.

And here the issues start. In the constructor of the Node I create the
ChildNodes:

_ChildNodes = new NodeList<Node<Object>> (this);

And the issue is: this blows. And I have no clue why. The error messages
are:

Error 2 The best overloaded method match for
'Foundation.Nodes.NodeList<Foundation.Nodes.Node<o bject>>.NodeList(Foundation.Nodes.Node<object>)'
has some invalid arguments
C:\WORK\ThonaConsulting\EntityBroker\03.0\Foundati on\Nodes\Node.cs 29 18
Foundation

Error 3 Argument '1': cannot convert from 'Foundation.Nodes.Node<T>' to
'Foundation.Nodes.Node<object>'
C:\WORK\ThonaConsulting\EntityBroker\03.0\Foundati on\Nodes\Node.cs 29 46
Foundation
Now, this I simply do not understand. The argument "this" is a Node<T> -
and is not convertible to Node<object>? Why not? T is supposed to be a
class, and object is the base-class of all classes. Also, I cano not even
cast this:

_ChildNodes = new NodeList<Node<Object>> ((Node<T>)this);

produces the exactly SAME error. I simply do not understand why. As I
said, the case should be totally valid in my optinion.

Anyone a clue? This starts to look like a compiler error to me, but I
still fear I just overlook something. I mean, this is created WITHIN A
node, so thi sshould be totally valid, or?

Thomas Tomiczek

Nov 17 '05 #2
Nicholas,

I've been curious about this problem although I haven't moved to C# 2.0
yet.

An interface is a good idea. Could you not also create a non-qualified
Node type and inherit all Node<T> types from that? Then you could say
simply "Node" with no qualification to indicate any type of Node<T>.
Would that also work?

Nov 17 '05 #3
Bruce,

That would be fine as well. Either way would work. However, it the
type definition gets messy that way because you have one property returning
the value as object (on the base), and another returning the type-safe value
(on the derived generic class). With the interface, you don't clutter up
the public face of the type as much.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Bruce Wood" <br*******@canada.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com...
Nicholas,

I've been curious about this problem although I haven't moved to C# 2.0
yet.

An interface is a good idea. Could you not also create a non-qualified
Node type and inherit all Node<T> types from that? Then you could say
simply "Node" with no qualification to indicate any type of Node<T>.
Would that also work?

Nov 17 '05 #4
Good point. In order to resolve that problem you would have to make the
non-generic base class Node into a runt class with only those methods
and properties that did not differentiate by the argument type in the
generic version. Given that, it would practically become an interface
anyway.

So, yes, I can see that an interface is a better way to solve the
problem.

Nov 17 '05 #5
Whow. What a fuckup.

So, if A is Subclass of B

then c<A> is NOT a subclass of c<B>?

This makes a lot of things way more complicated.

Is there a part of the documentation describing this?

It looks like I HAVE to go with this interface thing - personally I must say
I hate this.

Thomas

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:OF*************@TK2MSFTNGP12.phx.gbl...
Thomas,

The reason for this is that with generics, if you have a class B, that
inherits from A, then C<B> does NOT inherit from C<A>. The same goes for
casting.

To get around this, you should have a non-generic interface which
exposes the functionality of your node, and pass that around to the
constructor of your node class.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"Thomas Tomiczek" <t.********@thona-consulting.com> wrote in message
news:uX**************@TK2MSFTNGP14.phx.gbl...
Ok, working my way through a complex library conversion to .NET 2.0 and
C# 2.0 with generics I am totally stuck on one thing -if anyone sees the
issue I would be more than glad.

The situation is that we have a tree of "Node" objects. A Node is a
visualizable item, like a component. THe menues of all or ouf
applications, for example, are node hierarchies that an adapter
transposes into a menu model.

Now, Nodes have an internal DataObject, which can hold the actual data -
often a business object. This was so far a Object, now it will be T.

So, the definition of Node looks like this now:

public class Node<T> :
SmartObject,
INamed
where
T : class
{

The T is supposed to indicate the type of the DataObject, which can be
any class. There is a class NodeList that is basically a glorified IList
with a lot of additional functionality. It looks like this:

public class NodeList<T> :
ObjectBindingList<T>
where
T : Node<Object>
{

The idea is that a NodeList can hold any Node and should be
strong-typable for this. Now, here the issues come. A Node itself has a
Collection "Children". This is similar to the collection if children in
the component hierarchy. Nodes are not restricted to subtypes - and the
constructor of the NodeList can take a Node that is the parent. If there
is a parent in a NodeList, there is a lot of stuff going on when you
add/remove thigs. So, there is aconstructor like this:

public NodeList(Node<Object> Parent)

As you can see, ANY Node can be the parent.

And here the issues start. In the constructor of the Node I create the
ChildNodes:

_ChildNodes = new NodeList<Node<Object>> (this);

And the issue is: this blows. And I have no clue why. The error messages
are:

Error 2 The best overloaded method match for
'Foundation.Nodes.NodeList<Foundation.Nodes.Node<o bject>>.NodeList(Foundation.Nodes.Node<object>)'
has some invalid arguments
C:\WORK\ThonaConsulting\EntityBroker\03.0\Foundati on\Nodes\Node.cs 29 18
Foundation

Error 3 Argument '1': cannot convert from 'Foundation.Nodes.Node<T>' to
'Foundation.Nodes.Node<object>'
C:\WORK\ThonaConsulting\EntityBroker\03.0\Foundati on\Nodes\Node.cs 29 46
Foundation
Now, this I simply do not understand. The argument "this" is a Node<T> -
and is not convertible to Node<object>? Why not? T is supposed to be a
class, and object is the base-class of all classes. Also, I cano not even
cast this:

_ChildNodes = new NodeList<Node<Object>> ((Node<T>)this);

produces the exactly SAME error. I simply do not understand why. As I
said, the case should be totally valid in my optinion.

Anyone a clue? This starts to look like a compiler error to me, but I
still fear I just overlook something. I mean, this is created WITHIN A
node, so thi sshould be totally valid, or?

Thomas Tomiczek


Nov 17 '05 #6
No, no. It's not a fuck-up by any means. It's the only way that
generics can logically work. Think of what would happen if, as you
said, A being a subclass of B would make c<A> a subclass of c<B>. Take
List<T> for example.

The whole point of List<T> is to provide a type-safe list that
guarantees that all of the things in List<Car>, for example, are Cars.
If List<Car> were a subclass of List<Object> then List<Car> would
export of all its methods (such as .Add(Car T)) as well as all of the
methods of List<Object> (such as .Add(Object T)).

Just to make that clear, it would be (conceptually) something like
this:

public class List<Object>
{
public void Add(Object T) { ... }
}

public class List<Car> : List<Object>
{
public void Add(Car T) { ... }
}

Of course, that's junk code... it's just to give you the conceptual
idea. So what would this do? It would mean that List<Car> would export
_two_ Add methods. One that adds a Car to the list, another that adds
an Object to the list (via the base method in List<Object>). So now we
just lost type safety in the list! Now you can add any object you like
to the list, and you can no longer guarantee that the list will always
contain Cars, so you just lost all of the benefit of generics: you
might as well go back to plain old List!

Each type that you build from a generic has no inheritance relationship
to the other types built from that same generic unless you specifically
indicate one. I know it seems illogical at first glance, but
automatically creating such relationships would render generics useless.

Nov 17 '05 #7

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

Similar topics

25
by: PyPK | last post by:
What possible tricky areas/questions could be asked in Python based Technical Interviews?
27
by: Bernardo Heynemann | last post by:
How can I use Generics? How can I use C# 2.0? I already have VS.NET 2003 Enterprise Edition and still can´t use generics... I´m trying to make a generic collection myCollection<vartype> and...
2
by: Mr.Tickle | last post by:
So whats the deal here regarding Generics in the 2004 release and templates currently in C++?
2
by: Mark Sandfox | last post by:
I have a tricky control validation issue. I have probably designed this the wrong way but here is what I have. I have 6 TextBoxes; tbPN, tbA, tbC, tbS, tbZ, tbDOB and there are 20 of each with...
12
by: Michael S | last post by:
Why do people spend so much time writing complex generic types? for fun? to learn? for use? I think of generics like I do about operator overloading. Great to have as a language-feature, as...
5
by: anders.forsgren | last post by:
This is a common problem with generics, but I hope someone has found the best way of solving it. I have these classes: "Fruit" which is a baseclass, and "Apple" which is derived. Further I have...
9
by: sloan | last post by:
I'm not the sharpest knife in the drawer, but not a dummy either. I'm looking for a good book which goes over Generics in great detail. and to have as a reference book on my shelf. Personal...
7
by: SpotNet | last post by:
Hello NewsGroup, Reading up on Generics in the .NET Framework 2.0 using C# 2005 (SP1), I have a question on the application of Generics. Knowingly, Generic classes are contained in the...
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...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

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.