|
|
||||||
|
#1
|
|
|
|
|
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 |
|
|
|
#2
|
|
|
|
|
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. |
|
#3
|
|
|
|
|
Ashish <asharma> 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. |
|
#4
|
|
|
|
|
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: [..] |
|
#5
|
|
|
|
|
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: [..] |
|
#6
|
|
|
|
|
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. |
|
#7
|
|
|
|
|
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. |
|
#8
|
|
|
|
|
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: [..] |
|
#9
|
|
|
|
|
Ashish <asharma> 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. |
|
|
| Similar Threads | |
| Generics - type casting 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... |
|
| .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<T> where T : MyItemClass,... |
|
| .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<T> where T : MyItemClass,... |
|
| C#, Generics and casting Dear All, I've a question related to Generics and casting in c# 2.0. I've a class called Client which implements interface IClient. I'd like to do: LinkedList<Client>... |
|
| Type Casting With Generics I've been reading a discussion thread at [..] regarding typecasting generic collections to classical collections and vice-a-versa I faced a similar problem and solved it... |
|
|
All times are GMT. The time now is 04:32 PM. | Privacy Policy
|