473,396 Members | 1,608 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.

Upcast of generics in C# 3.0

Hello,

I was wondering if C# 3.0 finally supported generic upcasting. Consider the
following code which does work in C# 2:

string[] xs = {"this", "is", "a", "test"};
object[] ys = xs;

Now, analogously, I would expect the following to work as well:

IEnumerable<stringxs = new string[] { "this", "is", "a", "test" };
IEnumerable<objectys = xs;

As of now, this doesn't work because C# is unable to perform the conversion.
Actually, it is obvious why this code doesn't work: it would require the
creation of a new object, an operation which is not generally supported for
generics at the moment.

However, there is actually no technical reason not to allow this in general
(a proposed solution would have the compiler generate implicit conversion
methods, which, unfortunately, is not possible at the moment either because
the current version of C# does not allow to formulate the required
constraint).

So, long story short, my question: Does this work in C# 3.0? And if it
doesn't: Is there a sensible reason for this? I need this kind of code
constantly and the workarounds I have to use are nothing short of annoying.
Aug 2 '07 #1
10 4995

"Konrad Rudolph" <Konrad Ru*****@discussions.microsoft.comwrote in message
news:27**********************************@microsof t.com...
Hello,

I was wondering if C# 3.0 finally supported generic upcasting. Consider
the
following code which does work in C# 2:

string[] xs = {"this", "is", "a", "test"};
object[] ys = xs;

Now, analogously, I would expect the following to work as well:

IEnumerable<stringxs = new string[] { "this", "is", "a", "test" };
IEnumerable<objectys = xs;

As of now, this doesn't work because C# is unable to perform the
conversion.
<snip>
I need this kind of code
constantly and the workarounds I have to use are nothing short of
annoying.
Could you provide an example where you need this.

Kind Regards,
Allan Ebdrup
Aug 2 '07 #2

"Allan Ebdrup" <eb****@noemail.noemailwrote in message
news:eh**************@TK2MSFTNGP06.phx.gbl...
>
"Konrad Rudolph" <Konrad Ru*****@discussions.microsoft.comwrote in
message news:27**********************************@microsof t.com...
<snip>
>IEnumerable<stringxs = new string[] { "this", "is", "a", "test" };
IEnumerable<objectys = xs;
Why do you need ys to be IEnumerable<object>
If it's because you want to pass it to a method (M) that takes an
IEnumerable<objectparameter like this:

public void M(IEnumerable<objectparameter){...}

You could chang M to generic method like this:

public void M<T>(IEnumerable<Tparameter) {...}

that way you can pass both IEnumerable<stringand IEnumerable<objectto M

IEnumerable<stringxs = ...
IEnumerable<objectys = ...
M(xs); //this is valid
M(ys); //this is valid

The reason you dont have to specify T when calling M is because the type can
be inferred.
This way you can also pecify a method with a parameter of the type
IEnumerable<IMyInterfacelike this

public void M<T>(IEnumerable<Tparameter) where T : IMyInterface {...}

Does this help any?

Kind Regards,
Allan Ebdrup
Aug 2 '07 #3
Considering the immense number of requests for covariance in future C#
versions, this additional thread is somewhat redundant.
Aug 2 '07 #4

"Konrad Rudolph" <Konrad Ru*****@discussions.microsoft.comwrote in message
news:27**********************************@microsof t.com...
Hello,

I was wondering if C# 3.0 finally supported generic upcasting. Consider
the
following code which does work in C# 2:

string[] xs = {"this", "is", "a", "test"};
object[] ys = xs;
In fact, this should not be allowed. The only reason .NET has it was to
attract Java programmers who have had that bug for a very long time.
>
Now, analogously, I would expect the following to work as well:

IEnumerable<stringxs = new string[] { "this", "is", "a", "test" };
IEnumerable<objectys = xs;
Since IEnumerable only allows reading, this should be allowed. But it's not
the case for all interfaces. Also, you wouldn't want the compiler to infer
which interfaces are covariant or contravariant, because only the developer
knows whether the interface is likely to remain that way. There ought to be
an attribute to mark interfaces covariant or contravariant, but as far as I
know you can't pass type placeholders to attributes, nor even the actual
type. So without a significant redesign of .NET, you won't get that
behavior.
Aug 2 '07 #5
So without a significant redesign of .NET, you won't get that
behavior.
Well, as far as I know the .NET CTS actually *does* allow generic covariance
and contravariance. C# simply doesn't implement it. Perhaps the most obvious
solution would be to introduce Java-style generic wildcards.
Aug 2 '07 #6
Konrad,

No, this is not supported in C# 3.0, and there is a good reason for it.

Instead of using the IEnumerable<Tinterface, lets use List<T>
instances. Say for example you had this abstract class:

abstract class Animal {}

And the following concrete implementations:

class Dog : Animal {}
class Cat : Animal {}

If you then created a list of Dogs, like so:

List<Dogd = new List<Dog>();

Assume you allowed the cast, as you suggest, and did this:

List<Animala = d;

Remember, when you cast, you don't actually change the type of what the
variable is referencing. While variable a is of type List<Animalit points
to an instance of List<Dog>.

Now, because you have a List<Animalyou should be able to do this:

a.Add(new Cat());

Because a really points to a List<Dog>, you get a runtime exception.

Now, it could be argued that you want this behavior, but this is the
reason why it's not currently supported, or will be supported in C# 3.0.

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

"Konrad Rudolph" <Konrad Ru*****@discussions.microsoft.comwrote in message
news:27**********************************@microsof t.com...
Hello,

I was wondering if C# 3.0 finally supported generic upcasting. Consider
the
following code which does work in C# 2:

string[] xs = {"this", "is", "a", "test"};
object[] ys = xs;

Now, analogously, I would expect the following to work as well:

IEnumerable<stringxs = new string[] { "this", "is", "a", "test" };
IEnumerable<objectys = xs;

As of now, this doesn't work because C# is unable to perform the
conversion.
Actually, it is obvious why this code doesn't work: it would require the
creation of a new object, an operation which is not generally supported
for
generics at the moment.

However, there is actually no technical reason not to allow this in
general
(a proposed solution would have the compiler generate implicit conversion
methods, which, unfortunately, is not possible at the moment either
because
the current version of C# does not allow to formulate the required
constraint).

So, long story short, my question: Does this work in C# 3.0? And if it
doesn't: Is there a sensible reason for this? I need this kind of code
constantly and the workarounds I have to use are nothing short of
annoying.
Aug 2 '07 #7
On Aug 2, 1:53 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospamwrote:

<snip>
There ought to be
an attribute to mark interfaces covariant or contravariant, but as far as I
know you can't pass type placeholders to attributes, nor even the actual
type. So without a significant redesign of .NET, you won't get that
behavior.
I don't think there's an attribute for covariance/contravariance - I
think there's something in the "plain" metadata for the type.

It's unclear to me whether existing framework types could have the
covariance/contravariance which already exists in the CLR applied
retrospectively without breaking things. I suspect it'll never happen,
effectively :(

Jon

Aug 2 '07 #8
On Aug 2, 2:12 pm, Konrad Rudolph
<KonradRudo...@discussions.microsoft.comwrote:
So without a significant redesign of .NET, you won't get that
behavior.

Well, as far as I know the .NET CTS actually *does* allow generic covariance
and contravariance.
Only of interfaces, and only where it's safe to do so. It could apply
to IEnumerable<Tbut not to IList<Tor List<T>. Most of the requests
I've seen have been around List<T>, which wouldn't benefit.
C# simply doesn't implement it.
Neither do any framework types.
Perhaps the most obvious
solution would be to introduce Java-style generic wildcards.
I *believe* that only works as it does in Java because of type
erasure.

Jon

Aug 2 '07 #9

"Konrad Rudolph" <Ko***********@discussions.microsoft.comwrote in message
news:6B**********************************@microsof t.com...
>So without a significant redesign of .NET, you won't get that
behavior.

Well, as far as I know the .NET CTS actually *does* allow generic
covariance
and contravariance. C# simply doesn't implement it. Perhaps the most
obvious
solution would be to introduce Java-style generic wildcards.
A google for "Common Type System" and "covariance" returns countless hits,
changing to "generic covariance" returns exactly zero. Can you provide a
reference?
Aug 2 '07 #10
On Aug 2, 2:32 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospamwrote:
A google for "Common Type System" and "covariance" returns countless hits,
changing to "generic covariance" returns exactly zero. Can you provide a
reference?
I can!

At least, I'm not sure whether it's part of the CTS itself, but the
CLI spec talks about it.

Here's Rick Byers on it:

http://blogs.msdn.com/rmbyers/archiv...16/375079.aspx

Jon

Aug 2 '07 #11

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

Similar topics

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++?
23
by: Luc Vaillant | last post by:
I need to initialise a typed parameter depending of its type in a generic class. I have tried to use the C++ template form as follow, but it doesn't work. It seems to be a limitation of generics...
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...
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...
1
by: Vladimir Shiryaev | last post by:
Hello! Exception handling in generics seems to be a bit inconsistent to me. Imagine, I have "MyOwnException" class derived from "ApplicationException". I also have two classes...
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...
8
by: jonpb | last post by:
Hi, Is it possible to define a implicit operator from base to derived types in C#? I have a Point class and would like to derive a Vector class from it and add a couple new vector related...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.