![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | Upcasting to List<ISomeInteface> ? 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<SomeClass>, it seems like I should be able to assign it, or at least cast it, to a List<ISomeInterface>.... but I can't. It won't compile. As it stands, every time I own a List<SomeClass> and want to pass it to a method that accepts a List<ISomeInterface>, I have to create a new List<ISomeInterface> and populate it with the data from List<SomeClass>. 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 |
My System Specs![]() |
| | #2 (permalink) |
| | Re: Upcasting to List<ISomeInteface> ? On Wed, 02 Apr 2008 10:41:31 -0700, Jules Winfield <Jules.Winfield@xxxxxx> wrote: Quote: > 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<SomeClass>, it seems like I should be able to assign > it, > or at least cast it, to a List<ISomeInterface>.... but I can't. It won't > compile. covariance" to see more detailed explanations. But the short answer is: interface ISomeInterface { } class SomeClass : ISomeInterface { } class SomeOtherClass : ISomeInterface { } List<SomeClass> list1 = new List<SomeClass>(); List<ISomeInterface> list2 = list1; // suppose this were allowed list2.Add(new SomeOtherClass()); Then all of the sudden, you've got an instance of SomeOtherClass in your List<SomeClass>. Hopefully it's obvious why that's bad. Quote: > As it stands, every time I own a List<SomeClass> and want to pass it to a > method that accepts a List<ISomeInterface>, I have to create a new > List<ISomeInterface> and populate it with the data from List<SomeClass>. > 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? 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<ISomeInterface> in the first place. Yes, the "least-common-denominator" approach sacrifices some of the type safety of generics, but then that's what you're asking to do in the first place. If the overhead of converting instances of the List<T> class back and forth bothers you that much, then perhaps that's the solution you should take. Pete |
My System Specs![]() |
| | #3 (permalink) |
| | Re: Upcasting to List<ISomeInteface> ? Hello, with .NET 3.5 and its LINQ extenstion methods you can write myList.Cast<ISomeInterface>(). Kind regards, Henning Krause "Jules Winfield" <Jules.Winfield@xxxxxx> wrote in message news:buGdnXs975nWWG7anZ2dnUVZ_jOdnZ2d@xxxxxx Quote: > 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<SomeClass>, it seems like I should be able to assign it, > or at least cast it, to a List<ISomeInterface>.... but I can't. It won't > compile. > > As it stands, every time I own a List<SomeClass> and want to pass it to a > method that accepts a List<ISomeInterface>, I have to create a new > List<ISomeInterface> and populate it with the data from List<SomeClass>. > 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 > |
My System Specs![]() |
| | #4 (permalink) |
| | Re: Upcasting to List<ISomeInteface> ? >>>> Then all of the sudden, you've got an instance of SomeOtherClass in your List<SomeClass>. Hopefully it's obvious why that's bad. <<<< Ah, yes, this makes sense. I should've thought of that. Thanks for the explanation. |
My System Specs![]() |
| | #5 (permalink) |
| | Re: Upcasting to List<ISomeInteface> ? Jules Winfield wrote: Quote: > 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<SomeClass>, it seems like I should be able to assign it, > or at least cast it, to a List<ISomeInterface>.... but I can't. It won't > compile. > Quote: > Do you have a more efficient approach that I could employ? > Then when you need to pass your List<SomeClass> you can do as such: List<SomeClass> myList = LoadList(); SomeMethod(myList.ToArray()); --- void SomeMethod(IEnumerable<ISomeInterface Arrays are Covariant in c# so this will work. HTH JB |
My System Specs![]() |
| | #6 (permalink) |
| | Re: Upcasting to List<ISomeInteface> ? 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<T> with IList<T> or IEnumerable<T>... The point is: it isn't that "List<Foo> inherits from List<IFoo>", but rather that you want a list of [things] where those [things] inherit from IFoo - "List<T> 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<Foo> foos = new List<Foo> { new Foo {Bar = 5}, new Foo {Bar = 7} }; //SomeMethod(foos); // ERROR doesn't compile SomeOtherMethod(foos); } static void SomeMethod(List<IFoo> foos) {} static void SomeOtherMethod<T>(List<T> foos) where T : IFoo { foreach (T foo in foos) { Console.WriteLine(foo.Bar); } } } |
My System Specs![]() |
| | #7 (permalink) |
| | Re: Upcasting to List<ISomeInteface> ? thanks for the suggestions; they're much appreciated and they've given me more of an appreciation for the way c# is designed. |
My System Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| Creating a distribution list from a long cc list | Vista mail | |||
| Problem copying list of contacts into a new group list | Vista mail | |||
| add my contact list to safe senders list | Vista mail | |||
| converting email list to mailing list | .NET General | |||
| Network List Service is missing from the list of services | Network & Sharing | |||