Re: Casting generic collections & inheritance
- From: "Marc Gravell" <mgravell@xxxxxx>
- Date: Fri, 13 Jan 2006 12:47:33 -0000
Random aside: the logic I can see here makes perfect sence for anything that
allows addition etc - however, some casts could be sensible defined. In
particular (and most usefully) couldn't a List<X> quite safely implement
IEnumerable<T> for each T in X's inheritance tree?
Unless I am missing something this fails at the moment, but would be very
useful (to me, at least).
Example (which doesn't work) below.
Any thoughts? Am I missing an obvious "this wouldn't work because..."?
public class A {
public readonly string Name; // [sic] for brevity / demo
public A(string name) { name = Name; }
}
public class B : A {
public readonly int ID;
public B(string name, int id) : base(name) { id = ID; }
}
public class Program {
public static void Main() {
List<B> list = new List<B>();
list.Add(new B("Fred", 1));
list.Add(new B("Barney", 2));
list.Add(new B("Wilma", 3));
list.Add(new B("Betty", 4));
// *** following fails (as per spec) at runtime
// (would be nice if a: worked, and b: didn't need cast)
IEnumerable<A> items = (IEnumerable<A>) list;
foreach(A item in items) {
Console.WriteLine(item.Name);
}
Console.ReadLine();
}
}
"Jon Skeet [C# MVP]" <skeet@xxxxxxxxx> wrote in message
news:1137081986.209287.87140@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Michael Bray wrote:
>> > No it's not. If you could treat a Queue<string> as a Queue<object>
>> > then you could add a new object() to it - and suddenly anything
>> > viewing it
>> > as a Queue<string> would be in trouble.
>>
>> Jon, this is backwards to what Adam is saying... Its not that we want
>> to insert objects into the List<string> but we (well, me at least) would
>> like to be able to, for example, pass a List<string> to a function that
>> takes a List<object>.
>
> That's *exactly* what I said - if you could pass a List<string> to
> something expecting List<object> that's treating a List<string> as a
> List<object>, isn't it?
>
> The method you would pass the list to could do:
>
> theList.Add (new object());
>
> What would you expect to happen at that point? The caller is still
> expecting every element to be a string, so either you allow it and they
> blow up when they use the element as a string, or you blow up at the
> call to Add (which is what array covariance effectively does).
>
>> So for example, something like this is not possible, but it sure would
>> be nice:
>
> <snip>
>
>> Although after writing this example, I can see where the problem is...
>> the ShowNames function in this case doesn't modify the list, but that's
>> only because of the nature of the function. Some other function that
>> took a List<Person> might want to modify it and add a Person object
>> which would violate the definition of the List<Farmer>. So I guess it
>> makes sense after all! :)
>
> Exactly. That's what I was trying to say. Just out of interest, how
> could I have expressed it more clearly? It's a fairly common question -
> I'd like to know how to address it better. Would including source code
> have helped.
>
>> For anyone else following this thread, though, here's two nice ways to
>> convert (for Lists, at least from one type to another). Although I will
>> add that in light of the above, this should only be used for temporary
>> conversion in the case that you want to pass a List<DerivedClass> to a
>> function that processes a List<BaseClass> in a read-only fashion.
>>
>> otherPeople = new List<Person>(farmers.ToArray());
>>
>> otherPeople = farmers.ConvertAll(new Converter<Farmer, Person>(
>> delegate(Farmer f) { return (Person)f; }
>> ));
>
> I haven't tried, but I'm sure there's an easy way of writing a generic
> converter that can always do an identity conversion (i.e. convert from
> S to T where S : T).
>
>> The second one actually is more generic and doesn't even require that
>> the two classes be a base/derived class pair. In the example given,
>> however, this is the case, which is why the anonymous method code is
>> just a simple cast from Farmer to Person.
>
> In fact, the cast isn't even needed, is it?
>
> Jon
>
.
- Follow-Ups:
- Re: Casting generic collections & inheritance
- From: Jon Skeet [C# MVP]
- Re: Casting generic collections & inheritance
- From: Marc Gravell
- Re: Casting generic collections & inheritance
- From: Marc Gravell
- Re: Casting generic collections & inheritance
- References:
- Casting generic collections & inheritance
- From: Adam Clauss
- Re: Casting generic collections & inheritance
- From: Joanna Carter [TeamB]
- Re: Casting generic collections & inheritance
- From: Adam Clauss
- Re: Casting generic collections & inheritance
- From: Jon Skeet [C# MVP]
- Re: Casting generic collections & inheritance
- From: Michael Bray
- Re: Casting generic collections & inheritance
- From: Jon Skeet [C# MVP]
- Casting generic collections & inheritance
- Prev by Date: Re: O/R Mapper
- Next by Date: Re: How to make Windows inaccessible from my software user?
- Previous by thread: Re: Casting generic collections & inheritance
- Next by thread: Re: Casting generic collections & inheritance
- Index(es):
Relevant Pages
|