Upcasting to List<ISomeInteface> ?

Upcasting to List<ISomeInteface> ?

am 02.04.2008 19:41:31 von Jules Winfield

One thing I've never really understood about C# is the inability to upcast
generics based on templated type. If I have:

interface ISomeInterface{}

and

class SomeClass:ISomeInterface{}

and I have a List, it seems like I should be able to assign it,
or at least cast it, to a List.... but I can't. It won't
compile.

As it stands, every time I own a List and want to pass it to a
method that accepts a List, I have to create a new
List and populate it with the data from List.
I've created a template method to handle the work for me but I'd like to
avoid the needless CLR overhead involved in creating these intermediate
List<> objects.

Do you have a more efficient approach that I could employ?

Jules

Re: Upcasting to List<ISomeInteface> ?

am 02.04.2008 19:50:01 von Peter Duniho

On Wed, 02 Apr 2008 10:41:31 -0700, Jules Winfield =

wrote:

> One thing I've never really understood about C# is the inability to =

> upcast
> generics based on templated type. If I have:
>
> interface ISomeInterface{}
>
> and
>
> class SomeClass:ISomeInterface{}
>
> and I have a List, it seems like I should be able to assign=
=

> it,
> or at least cast it, to a List.... but I can't. It won=
't
> compile.

Nor should it, IMHO. You can search this newsgroup for "generic =

covariance" to see more detailed explanations. But the short answer is:=


interface ISomeInterface { }
class SomeClass : ISomeInterface { }
class SomeOtherClass : ISomeInterface { }

List list1 =3D new List();
List list2 =3D list1; // suppose this were allowed

list2.Add(new SomeOtherClass());

Then all of the sudden, you've got an instance of SomeOtherClass in your=
=

List. Hopefully it's obvious why that's bad.

> As it stands, every time I own a List and want to pass it t=
o a
> method that accepts a List, I have to create a new
> List and populate it with the data from List >.
> I've created a template method to handle the work for me but I'd like =
to
> avoid the needless CLR overhead involved in creating these intermediat=
e
> List<> objects.
>
> Do you have a more efficient approach that I could employ?

My understanding is that the .NET run-time actually supports covariance =
in =

generics. So maybe there's a non-C# way around the issue, if you really=
=

want to do that.

It seems to me that an alternative route would be to maintain your list =
as =

a List in the first place. Yes, the =

"least-common-denominator" approach sacrifices some of the type safety o=
f =

generics, but then that's what you're asking to do in the first place. =
If =

the overhead of converting instances of the List class back and forth=
=

bothers you that much, then perhaps that's the solution you should take.=


Pete

Re: Upcasting to List<ISomeInteface> ?

am 02.04.2008 21:17:58 von newsgroups_remove

Hello,

with .NET 3.5 and its LINQ extenstion methods you can write

myList.Cast().

Kind regards,
Henning Krause

"Jules Winfield" wrote in message
news:buGdnXs975nWWG7anZ2dnUVZ_jOdnZ2d@giganews.com...
> One thing I've never really understood about C# is the inability to upcast
> generics based on templated type. If I have:
>
> interface ISomeInterface{}
>
> and
>
> class SomeClass:ISomeInterface{}
>
> and I have a List, it seems like I should be able to assign it,
> or at least cast it, to a List.... but I can't. It won't
> compile.
>
> As it stands, every time I own a List and want to pass it to a
> method that accepts a List, I have to create a new
> List and populate it with the data from List.
> I've created a template method to handle the work for me but I'd like to
> avoid the needless CLR overhead involved in creating these intermediate
> List<> objects.
>
> Do you have a more efficient approach that I could employ?
>
> Jules
>

Re: Upcasting to List<ISomeInteface> ?

am 03.04.2008 00:15:16 von Jules Winfield

>>>>
Then all of the sudden, you've got an instance of SomeOtherClass in your
List. Hopefully it's obvious why that's bad.
<<<<

Ah, yes, this makes sense. I should've thought of that. Thanks for the
explanation.

Re: Upcasting to List<ISomeInteface> ?

am 03.04.2008 00:21:09 von John B

Jules Winfield wrote:
> One thing I've never really understood about C# is the inability to upcast
> generics based on templated type. If I have:
>
> interface ISomeInterface{}
>
> and
>
> class SomeClass:ISomeInterface{}
>
> and I have a List, it seems like I should be able to assign it,
> or at least cast it, to a List.... but I can't. It won't
> compile.
>
<...>
> Do you have a more efficient approach that I could employ?
>
You could declare your method to use IEnumerable instead.
Then when you need to pass your List you can do as such:

List myList = LoadList();
SomeMethod(myList.ToArray());

--- void SomeMethod(IEnumerable
Arrays are Covariant in c# so this will work.


HTH
JB

Re: Upcasting to List<ISomeInteface> ?

am 03.04.2008 08:56:47 von Marc Gravell

As an aside, there is another useful trick; use a generic method and
type-inference; an example is below - note that in this case I could also
replace List with IList or IEnumerable...

The point is: it isn't that "List inherits from List", but rather
that you want a list of [things] where those [things] inherit from IFoo -
"List where T : IFoo"

Marc

using System;
using System.Collections.Generic;

interface IFoo {
int Bar {get;set;}
}
class Foo : IFoo {
public int Bar {get;set;}
}
static class Program
{
static void Main()
{
List foos = new List {
new Foo {Bar = 5}, new Foo {Bar = 7}
};
//SomeMethod(foos); // ERROR doesn't compile
SomeOtherMethod(foos);
}
static void SomeMethod(List foos) {}
static void SomeOtherMethod(List foos) where T : IFoo
{
foreach (T foo in foos)
{
Console.WriteLine(foo.Bar);
}
}
}

Re: Upcasting to List<ISomeInteface> ?

am 03.04.2008 22:55:23 von Jules Winfield

thanks for the suggestions; they're much appreciated and they've given me
more of an appreciation for the way c# is designed.