472,988 Members | 2,290 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Generics and Type casting.

Hi all,

I have interface declared like

public IBaseInterface
{
}

then a generic collection like

public GCollection<T> Where T:IBaseInterface
{
}
then i have a class like

public class Address:IBaseInterface
{}
so i declare a collection of Address type

GCollection<Address> mcol = new GCollection<Address>();

then i try to type cast it to

GCollection<IBaseInterface> mysecondcol = (GCollection<IBaseInterface>)
mcol; // this throws type cast exception !

can someone explain why this is not allowed and what can be a way around ?

TIA
Feb 14 '06 #1
8 3297
Ashish,

You would have to declare the GCollection<Address> as
GCollection<IBaseInterface>.

The reason you have to do this is say you could perform the cast. Then,
when you try to add another class which implements IBaseInterface, but is
not Address, you would get an exception because of the invalid cast.

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

"Ashish" <as*****@thisisjunk.com> wrote in message
news:u4*************@tk2msftngp13.phx.gbl...
Hi all,

I have interface declared like

public IBaseInterface
{
}

then a generic collection like

public GCollection<T> Where T:IBaseInterface
{
}
then i have a class like

public class Address:IBaseInterface
{}
so i declare a collection of Address type

GCollection<Address> mcol = new GCollection<Address>();

then i try to type cast it to

GCollection<IBaseInterface> mysecondcol = (GCollection<IBaseInterface>)
mcol; // this throws type cast exception !

can someone explain why this is not allowed and what can be a way around ?

TIA

Feb 14 '06 #2
Ashish <as*****@thisisjunk.com> wrote:

<snip>
so i declare a collection of Address type

GCollection<Address> mcol = new GCollection<Address>();

then i try to type cast it to

GCollection<IBaseInterface> mysecondcol = (GCollection<IBaseInterface>)
mcol; // this throws type cast exception !

can someone explain why this is not allowed and what can be a way around ?


Does it even compile? I'd be surprised.

Generics aren't covariant in that way - and for good reason. Imagine
you wrote the code above, and then:

mysecondcol[0] = new SomeOtherImplementationOfIBaseInterface();

That will compile, but at runtime it would either have to throw an
exception, or end up with mcol not *really* being a collection of
Address.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Feb 14 '06 #3
hi Nicholas,
thanks for the reply,

this compiles properly but throws error at runtime, i can understand if
i try to add object of some other class and it throws error, but
IBaseEntity is a braoder type of Address so i should be able to hold a
reference ....

TIA

Nicholas Paldino [.NET/C# MVP] wrote:
Ashish,

You would have to declare the GCollection<Address> as
GCollection<IBaseInterface>.

The reason you have to do this is say you could perform the cast. Then,
when you try to add another class which implements IBaseInterface, but is
not Address, you would get an exception because of the invalid cast.

Hope this helps.

Feb 14 '06 #4
it compiles properly, and its okay if this throws runtime error on

mysecondcol[0] = new SomeOtherImplementationOfIBaseInterface();

but i should be able to hold a reference since Address is a narrower
type of IBaseEntity...

Jon Skeet [C# MVP] wrote:
Ashish <as*****@thisisjunk.com> wrote:

<snip>
so i declare a collection of Address type

GCollection<Address> mcol = new GCollection<Address>();

then i try to type cast it to

GCollection<IBaseInterface> mysecondcol = (GCollection<IBaseInterface>)
mcol; // this throws type cast exception !

can someone explain why this is not allowed and what can be a way around ?

Does it even compile? I'd be surprised.

Generics aren't covariant in that way - and for good reason. Imagine
you wrote the code above, and then:

mysecondcol[0] = new SomeOtherImplementationOfIBaseInterface();

That will compile, but at runtime it would either have to throw an
exception, or end up with mcol not *really* being a collection of
Address.

Feb 14 '06 #5
Ashish,

No, you shouldn't. There is no relation between
GCollection<IBaseInterface> and GCollection<Address>. The relation of the
type parameters does not ensure that you can cast between the two.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Ashish" <as*****@thisisjunk.com> wrote in message
news:e1*************@TK2MSFTNGP15.phx.gbl...
it compiles properly, and its okay if this throws runtime error on

mysecondcol[0] = new SomeOtherImplementationOfIBaseInterface();

but i should be able to hold a reference since Address is a narrower type
of IBaseEntity...

Jon Skeet [C# MVP] wrote:
Ashish <as*****@thisisjunk.com> wrote:

<snip>
so i declare a collection of Address type

GCollection<Address> mcol = new GCollection<Address>();

then i try to type cast it to

GCollection<IBaseInterface> mysecondcol = (GCollection<IBaseInterface>)
mcol; // this throws type cast exception !

can someone explain why this is not allowed and what can be a way around
?

Does it even compile? I'd be surprised.

Generics aren't covariant in that way - and for good reason. Imagine you
wrote the code above, and then:

mysecondcol[0] = new SomeOtherImplementationOfIBaseInterface();

That will compile, but at runtime it would either have to throw an
exception, or end up with mcol not *really* being a collection of
Address.

Feb 14 '06 #6
Ashish wrote:
it's okay if this throws runtime error on

mysecondcol[0] = new SomeOtherImplementationOfIBaseInterface();

but i should be able to hold a reference since Address is a narrower
type of IBaseEntity...


No, you shouldn't, because the whole point of generics is to catch
these things at compile time and therefore to avoid having to generate
code to trap invalid casts at runtime (which costs). If you were
allowed to do what you're proposing, then everywhere you used a generic
structure the compiler would also have to write in run-time type
checking, which would slow things down considerably.

You're looking at the from the point of view of a reader: "If I'm going
to read this collection, I don't care whether it's declared to be a
collection of type A, or a collection of some base type of A." All well
and good, but for the purposes of writing to the collection, it does
matter.

Don't forget: there's already a way to have a collection that you can
regulate using run-time type checking of its contents: use an
ArrayList. Remember that in the 1.1 world there were collections in
which you could place any type of object and you took care of type
checking yourself.

In the 2.0 world, generics added the capability to have collections
that were locked down to a particular type (or any type derived from
that particular type). There is no capability to "broaden the scope" of
what's allowed in the collection for certain purposes. A collection is
of a particular type and that's all there is to it. Any relaxation of
that rule comes with (undesirable) run-time costs.

The only reasonable exception I can see would be to allow you to cast a
*read-only* collection of class A to a *read-only* collection of any
ancestor of class A, but that's probably too specific to justify the
work it would take to shoehorn it into the language.

Feb 14 '06 #7
I see your point, but in my logic i dont know what type the collection
would be, apart from that it would be a type implementing IBaseEntity,

Is there a work around i could implement so somehow type cast into a
more generic collection ?

thanks again for your help

regards

Nicholas Paldino [.NET/C# MVP] wrote:
Ashish,

No, you shouldn't. There is no relation between
GCollection<IBaseInterface> and GCollection<Address>. The relation of the
type parameters does not ensure that you can cast between the two.

Feb 14 '06 #8
Ashish <as*****@thisisjunk.com> wrote:
it compiles properly


Please provide the code then. Here's some code which *doesn't* compile,
which is very similar to your code:

using System;
using System.IO;
using System.Collections.Generic;

class Test
{
static void Main (string[] args)
{
List<MemoryStream> m = new List<MemoryStream>();
List<IDisposable> i = (List<IDisposable>)m;
}
}

That's about as close to your code as I can get without seeing the
definition of GCollection etc.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Feb 14 '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...
8
by: Kris Jennings | last post by:
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...
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: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
3
SueHopson
by: SueHopson | last post by:
Hi All, I'm trying to create a single code (run off a button that calls the Private Sub) for our parts list report that will allow the user to filter by either/both PartVendor and PartType. On...

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.