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.