tags:

views:

120

answers:

3

In some library I create I have to use following cast:

public void Foo(IList<uint> uintsList) // I need to use uint in the interface for this method
{
    List<double> doublesList = uintsList.Cast<double>().ToList();
    // Do something with the doublesList
}

I assumed that cast uint -> double should be always valid, and during my test it always worked fine.

But in the application, which uses this method the InvalidCastException occured. Unfortunately I do not have access to this application. So here are my questions:

  • What could cause this exception occured? Isn't the cast uint->double always valid?
  • How can I secure my algorithm to avoid this exception?

EDIT
Of course, before casting I always perform check to avoid situation when uintsList is null or empty

EDIT 2 OK, the problem is solved, I changed the cast using the ConvertAll method, but still I don't understand how it could happen?
So this question still bothers me: how the same part of the code could run properly at my computer, and throw an exception at another? Different compiler/environment versions? Some specific settings? Can anyone tell me where should I seek for the reasons of this situation to avoid it in the future?

+3  A: 

See: http://stackoverflow.com/questions/2084493/c-converting-listint-to-listdouble

The cast uint -> double is valid, but you are casting a list of uints to a list of doubles. On most architectures the lists won't even the same size (in bytes) - you will need to create an entirely new list and cast each element individually. I would use ConvertAll:

List<double> doublesList = uintsList.ConvertAll(x => (double)x);
rjh
"On most archetectures the lists won't even the same size (in bytes)" This is totally irrelevant. The OP is *not casting* a `List<uint>` to `List<double>`. He is calling the `Enumerable.Cast` method passing a `List<uint>`. It takes a sequence and tries to cast each **individual element** of the list and generates a sequence of new type. It's totally different from casting a `List<uint>` to `List<double>`.
Mehrdad Afshari
`ConvertAll` works -> accepted. Thank you!
Gacek
+3  A: 

.Cast method is not meant to perform type conversion like that. It just performs conversions in the inheritance hierarchy.

The reason for this behavior is that the extension method signature takes an IEnumerable and not IEnumerable<T>. Consequently, getting the Current property of the enumerator returns an object to the Cast method. Of course, you can't unbox a value type of one type to another type directly. Basically, Cast will do something like:

int i = 42;
object o = i;
double d = (double)o; // fails.
Mehrdad Afshari
+1  A: 

looks like a duplicate of: this more general question

Rune FS