473,729 Members | 2,177 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Question about Generics

Hello,

I'm wondering if it's possible to do the following with Generics:

Let's say I have a generic member variable as part of a generic class
like this:

List<DLinqQuery <TDataContext >> _queries;

where DLinqQuery is a generic class that takes a type parameter
TDataContext.

This member variable is part of a generic class called
DLinqDataSource <TDataContext > and is exposed as a public property of
the specified type.

It is assumed that all TDataContext types will be derived from the
concrete class DataContext.

Now, let's say I derive a class from DataContext called MyDataContext.

I the create two concrete classes like this:

public class MyDataQuery : DLinqQuery<MyDa taContext>{}
public class MyDataSource : DLinqDataSource <MyDataContext> {}

I want to be able to override the property in the MyDataSource class to
return a List<MyDataQuer y> instead of the generic
List<DLinqQuery <TDataContext >> which would become
List<DLinqQuery <MyDataContex t> in an instantiation of MyDataSource.

Unfortunately, casting the base property value (which is a
List<DLinqQuery <MyDataContext> > to the type List<MyDataQuer y> just
doesn't work, but from a functional perspective it seems like that it
would.

Any ideas on whether this can be done?

Jun 30 '06 #1
11 2480
The reason you can not do this is because generic types are not
covariant (I believe that is the term). This means that if you have a type
Dog which derives from Animal, and a List<Dog>, you can not cast it to a
List<Animal>.

The reason for this is that when you have a class, Cat which derives
from Animal, and you have the new List<Animal> (cast from List<Dog>), that
list wouldn't know what to do with the Cat when it is added.

The workaround here is to define your classes like so:

public class MyDataQuery : DLinqQuery<MyDa taContext>{}

public class MyDataSource<T> : DLinqDataSource <T>{}

Then, when you declare your MyDataSource, you would do this:

MyDataSource<My DataQuery> ds = new MyDataSource<My DataQuery>();

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m
"ha************ ****@gmail.com" <ha*********@gm ail.com> wrote in message
news:11******** **************@ y41g2000cwy.goo glegroups.com.. .
Hello,

I'm wondering if it's possible to do the following with Generics:

Let's say I have a generic member variable as part of a generic class
like this:

List<DLinqQuery <TDataContext >> _queries;

where DLinqQuery is a generic class that takes a type parameter
TDataContext.

This member variable is part of a generic class called
DLinqDataSource <TDataContext > and is exposed as a public property of
the specified type.

It is assumed that all TDataContext types will be derived from the
concrete class DataContext.

Now, let's say I derive a class from DataContext called MyDataContext.

I the create two concrete classes like this:

public class MyDataQuery : DLinqQuery<MyDa taContext>{}
public class MyDataSource : DLinqDataSource <MyDataContext> {}

I want to be able to override the property in the MyDataSource class to
return a List<MyDataQuer y> instead of the generic
List<DLinqQuery <TDataContext >> which would become
List<DLinqQuery <MyDataContex t> in an instantiation of MyDataSource.

Unfortunately, casting the base property value (which is a
List<DLinqQuery <MyDataContext> > to the type List<MyDataQuer y> just
doesn't work, but from a functional perspective it seems like that it
would.

Any ideas on whether this can be done?

Jun 30 '06 #2
ha************* ***@gmail.com wrote:
Hello,

I'm wondering if it's possible to do the following with Generics:

Let's say I have a generic member variable as part of a generic class
like this:

List<DLinqQuery <TDataContext >> _queries;

where DLinqQuery is a generic class that takes a type parameter
TDataContext.

This member variable is part of a generic class called
DLinqDataSource <TDataContext > and is exposed as a public property of
the specified type.

It is assumed that all TDataContext types will be derived from the
concrete class DataContext.

Now, let's say I derive a class from DataContext called MyDataContext.

I the create two concrete classes like this:

public class MyDataQuery : DLinqQuery<MyDa taContext>{}
public class MyDataSource : DLinqDataSource <MyDataContext> {}

I want to be able to override the property in the MyDataSource class to
return a List<MyDataQuer y> instead of the generic
List<DLinqQuery <TDataContext >> which would become
List<DLinqQuery <MyDataContex t> in an instantiation of MyDataSource.

Unfortunately, casting the base property value (which is a
List<DLinqQuery <MyDataContext> > to the type List<MyDataQuer y> just
doesn't work, but from a functional perspective it seems like that it
would.

Any ideas on whether this can be done?


Hi,

This question has been asked a few times here. The answer I gave to one of
them was that you cannot cast it, because a List<A> is not, and is not a
derivative of a List<B> if A derives from B. They're two different types,
because the type is expressed as a result of the type name and it's type
parameters.

So, you'll have to write a function that will convert the
List<DLinqQuery <MyDataContext> > to List<MyDataQuer y>. Also, the definition
of override is to change the behaviour of a virtual method defined in a
base class, not to alter it's signature, e.g.:

public virtual bool foo ( int bar ) { ... }

Can only be overriden to change the behaviour of 'foo', not it's return
type, and not it's parameters.

The generic List class contains a generic method called ConvertAll<> which
can help you convert the list, or you can just enumerate through your list
and build a brand new one.

--
Hope this helps,
Tom Spink
Jun 30 '06 #3
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard .caspershouse.c omwrote:
The reason you can not do this is because generic types are not
covariant (I believe that is the term).
It is - although the CLR itself supports covariance. You can tell the
CLR that something is a list of "some type which is derived from Dog"
or "some type which is a super-type of Dog". However, C# doesn't expose
this, and neither do the framework libraries.

It's a bit of a shame - the Java libraries *do* expose this, and
although it's a fairly confusing topic, it can be very handy. With Mads
on the C# team now, I wouldn't be surprised to see
covariance/contravariance appear in a later version - although now the
standard libraries have been defined without support, the usefulness of
them would be very much diminished.

(I should say that this is one of the very few places where Java
generics are better than C# generics.)

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jul 2 '06 #4
Jon Skeet [C# MVP] wrote:
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard .caspershouse.c omwrote:
> The reason you can not do this is because generic types are not
covariant (I believe that is the term).

It is - although the CLR itself supports covariance. You can tell the
CLR that something is a list of "some type which is derived from Dog"
or "some type which is a super-type of Dog". However, C# doesn't expose
this, and neither do the framework libraries.

It's a bit of a shame - the Java libraries *do* expose this, and
although it's a fairly confusing topic, it can be very handy. With Mads
on the C# team now, I wouldn't be surprised to see
covariance/contravariance appear in a later version - although now the
standard libraries have been defined without support, the usefulness of
them would be very much diminished.
Hi Jon,
(I should say that this is one of the very few places where Java
generics are better than C# generics.)
I agree with that, very reluctantly. I've always found Java generics nasty,
since it's not a feature of the JVM, but a feature of the compiler,
unlike .NET which is a feature of the CLI, not the compiler, which IMHO,
the latter feels nicer. <g>

--
Hope this helps,
Tom Spink
Jul 2 '06 #5
Tom Spink <ts****@gmail.c omwrote:
(I should say that this is one of the very few places where Java
generics are better than C# generics.)

I agree with that, very reluctantly. I've always found Java generics nasty,
since it's not a feature of the JVM, but a feature of the compiler,
unlike .NET which is a feature of the CLI, not the compiler, which IMHO,
the latter feels nicer. <g>
It's certainly better to be part of the platform itself (although it's
still a feature of the compiler, of course. If the compiler doesn't
support generics, you're not going to be able to use them). I'd say
it's still nicer to have Java-style generics than not to have them at
all, but it would have been much better to have .NET-style generics,
even without covariance.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jul 2 '06 #6
Jon Skeet [C# MVP] <sk***@pobox.co mwrote:
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard .caspershouse.c omwrote:
The reason you can not do this is because generic types are not
covariant (I believe that is the term).

It is - although the CLR itself supports covariance. You can tell the
CLR that something is a list of "some type which is derived from Dog"
or "some type which is a super-type of Dog". However, C# doesn't expose
this, and neither do the framework libraries.

It's a bit of a shame - the Java libraries *do* expose this, and
although it's a fairly confusing topic, it can be very handy. With Mads
on the C# team now, I wouldn't be surprised to see
covariance/contravariance appear in a later version - although now the
standard libraries have been defined without support, the usefulness of
them would be very much diminished.

(I should say that this is one of the very few places where Java
generics are better than C# generics.)
A problem with enabling covariance and contravariance is that it would
add type-checks at the CLR level to operations which currently don't
need a type-check. For example, covariance of object arrays is enabled
in C#. As a result, all writes into an object array cause a runtime
type-check.

The type-safe way to enable covariance and contravariance is to limit
the methods callable on a generic parameter explicitly allowed to accept
covariant or contravariant values. Basically, variables of a covariant
type are allowed to return the covariant type in out or return
parameters only, while variables of a contravariant type are allowed to
accept values of a contravariant types only.

There is good coverage of this issue in a recent MS paper:

Variance and Generalized Constraints for C# Generics
Burak Emir, Andrew J. Kennedy, Claudio Russo, Dachuan Yu
July 2006

http://research.microsoft.com/resear...edings&id=1215

Direct link:
http://research.microsoft.com/~akenn...cs/ECOOP06.pdf

Discussion on Lambda the Ultimate:

http://lambda-the-ultimate.org/node/1573

-- Barry

--
http://barrkel.blogspot.com/
Jul 3 '06 #7
Barry Kelly <ba***********@ gmail.comwrote:
(I should say that this is one of the very few places where Java
generics are better than C# generics.)

A problem with enabling covariance and contravariance is that it would
add type-checks at the CLR level to operations which currently don't
need a type-check. For example, covariance of object arrays is enabled
in C#. As a result, all writes into an object array cause a runtime
type-check.
That's one sort of covariance, yes.
The type-safe way to enable covariance and contravariance is to limit
the methods callable on a generic parameter explicitly allowed to accept
covariant or contravariant values. Basically, variables of a covariant
type are allowed to return the covariant type in out or return
parameters only, while variables of a contravariant type are allowed to
accept values of a contravariant types only.
That's the sort of covariance/contravariance I was thinking of :)
Perhaps there ought to be two different terms for it...

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jul 3 '06 #8
Jon Skeet [C# MVP] <sk***@pobox.co mwrote:
Barry Kelly <ba***********@ gmail.comwrote:
(I should say that this is one of the very few places where Java
generics are better than C# generics.)
A problem with enabling covariance and contravariance is that it would
add type-checks at the CLR level to operations which currently don't
need a type-check. For example, covariance of object arrays is enabled
in C#. As a result, all writes into an object array cause a runtime
type-check.

That's one sort of covariance, yes.
The type-safe way to enable covariance and contravariance is to limit
the methods callable on a generic parameter explicitly allowed to accept
covariant or contravariant values. Basically, variables of a covariant
type are allowed to return the covariant type in out or return
parameters only, while variables of a contravariant type are allowed to
accept values of a contravariant types only.

That's the sort of covariance/contravariance I was thinking of :)
Perhaps there ought to be two different terms for it...
If one describes reading from an array as a method "T GetValue(int)",
and writing into an array as "void SetValue(int, T)", then there is an
exact correspondence between covariance/contravariance in classes and
covariance in arrays, as described above. They're the same thing. The
SetValue(int, T) method should be contravariant, not covariant - e.g.
considering arrays of dogs and mammals, if SetValue() is going to be the
only "method" called on the array, then one should be able to supply an
array of mammals where an array of dogs is expected. Slightly
counter-intuitive, perhaps, but that's where the "contra" comes in :)

The paper gives good coverage of a possible way of introducing it into
C#. My only concern is that it would confuse things, since reasoning
about covariance / contravariance can be a little tricky.

-- Barry

--
http://barrkel.blogspot.com/
Jul 3 '06 #9
Barry Kelly wrote:
That's the sort of covariance/contravariance I was thinking of :)
Perhaps there ought to be two different terms for it...

If one describes reading from an array as a method "T GetValue(int)",
and writing into an array as "void SetValue(int, T)", then there is an
exact correspondence between covariance/contravariance in classes and
covariance in arrays, as described above. They're the same thing.
Not quite (IMO). The CLR supports covariance/contravariance by allowing
a type to be declared as List<Stream+or List<Stream-for instance.
That is a sort of *declarative* covariance/contravariance which can
tell the compiler that it *will* support one of GetValue or SetValue
(and which one :) That's not the same as the runtime
covariance/contravariance of arrays in terms of compile-time type
safety, so it's worth making the distinction between them. The CLR
supports compile-time-unsafe covariance for arrays, but
compile-time-safe covariance/contravariance for generics. C# supports
compile-time-unsafe covariance for arrays, but has no concept of the
compile-time-safe generic covariance/contravariance supported by the
CLR.

Does that explain the distinction I make between the two sorts of
covariance any better?

Jon

Jul 3 '06 #10

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

Similar topics

5
1668
by: Matthew W. Jackson | last post by:
I had a question about the "using" statement and Generics in the next version of C#, and I was directed to this newsgroup. My question is: Will the following syntax be valid? using Int32ArrayList = System.GCollections.ArrayList<Int32>; .... Int32ArrayList myArrayList = new Int32ArrayList();
16
1835
by: bigtexan | last post by:
I would like to do the following and cannot figure it out. public class A<T> { public delegate T GetValueDelegate(A<T> var); public GetValueDelegate GetValue = new GetValueDelegate(B.GetValue); } public class B {
12
2740
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 it defines the language more completely. Great to use.
1
1891
by: Peter Kirk | last post by:
Hi I have never used generics before, and I was wondering if the following sort of use was acceptable/normal for a method: public IList<IPerson> GetPersons() { IList<IPerson> personList = new List<IPerson>(); ... // get the persons return personList;
9
5984
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 Experience Only, Please. ...
3
2601
by: Showjumper | last post by:
Back in asp.net 1.1 i made custom collection classes per Karl Seguin's article On the Way to Mastering ASP.NET: Introducing Custom Entity Classes to take advantage of strongly typed data. Now with generics i understand that one doesnt have to used these custom collections. So i want to move this 1.1 project to 2.0. I have been reading about generics but i geuss i dont really get hpw to implement them. For example i have 2 classees in the...
1
1677
by: Kevin S. Goff | last post by:
Hi, all, Hopefully this will make sense: I have 2 classes that implement the same generic interface. public interface IAgingReport<T> { T GetAgingReport(DateTime dAsOfDate); }
14
1704
by: cwineman | last post by:
Hello, I'm hoping to do something using Generics, but I'm not sure it's possible. Let's say I want to have a bunch of business objects and a data access class cooresponding to each business object. For each business object, I would have something like below: public class Apple { //apple stuff
4
4218
by: DeveloperX | last post by:
I'm having a play with EventHandlerList but the documentation is a bit ropey and I can't find any decent examples. It also doesn't seem to do what I was led to believe it would. I was under the impression that windows.forms controls used EventHandlerLists because generally most events aren't consumed so this saves memory. I can add a button to a form, and have this.button9.Click += new System.EventHandler(this.button9_Click);...
0
8913
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
1
9200
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6722
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6016
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4525
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4795
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3238
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2677
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2162
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.