I have a List of objects, which are of my type QuoteHeader
and I want to pass this list as a list of objects to a method which is able to accept a List<object>
.
My line of code reads...
Tools.MyMethod((List<object>)MyListOfQuoteHeaders);
But I get the following error at design time...
Cannot convert type 'System.Collections.Generic.List<MyNameSpace.QuoteHeader>'
to 'System.Collections.Generic.List<object>'
Do I need to do anything to my class to allow this? I thought that all classes inherit from object so I can't understand why this wouldn't work?
The constructor takes a Collection , but List is a subinterface of Collection , so you can just use the List<String> . This constructs unnecessary objects and can, if this is a big list, potentially take up a lot of memory. Just cast it.
you can always cast any object to any type by up-casting it to Object first. in your case: (List<Customer>)(Object)list; you must be sure that at runtime the list contains nothing but Customer objects.
Try the following: List<TestA> result = new List<TestA>(); List<TestB> data = new List<TestB>(); result. addAll(data);
The reason this is not legal is because it is not safe. Suppose it were legal:
List<Giraffe> giraffes = new List<Giraffe>(); List<Animal> animals = giraffes; // this is not legal; suppose it were. animals.Add(new Tiger()); // it is always legal to put a tiger in a list of animals
But "animals" is actually a list of giraffes; you can't put a tiger in a list of giraffes.
In C# this is, unfortunately, legal with arrays of reference type:
Giraffe[] giraffes = new Giraffe[10]; Animal[] animals = giraffes; // legal! But dangerous because... animals[0] = new Tiger(); // ...this fails at runtime!
In C# 4 this is legal on IEnumerable but not IList:
List<Giraffe> giraffes = new List<Giraffe>(); IEnumerable<Animal> animals = giraffes; // Legal in C# 4 foreach(Animal animal in animals) { } // Every giraffe is an animal, so this is safe
It is safe because IEnumerable<T>
does not expose any method that takes in a T.
To solve your problem you can:
List<object>
, and use unsafe array covariance.List<T>
IEnumerable<object>
and use C# 4.You can't cast List<OneType>
to List<OtherType>
as it is actually the instances of the list you want to cast, as well as the List itself.
there is an extension method which will allow you to do this (MSDN reference):
IEnumerable<Object> myNewEnumerable = myEnumerable.Cast<Object>();
This method will attempt to cast each instance of the list of one type to the other type and add them to a new enumerable. it will throw an exception if any instance can't be cast.
As far as the system is concerned the two types for your lists are just different types, so it is like saying:
A objectOfTypeA;
B objectOfTypeB = (B) objectofTypeA;
To be able to do the cast there would have to be an implicit or explicit conversion between the types available, which there isn't (unless you provided one, which you might be able to do).
you expect it to work because List<object>
will always be able to hold any type in another list, but when you think about it in those terms you can see why it doesn't.
I'm sure there is a more technically competent answer, but that is the gist of it I think.
you might be interested in reading Eric Lippert's series on Covariance and Contravariance as this may be helpful to you.
This question may also be useful
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With