I found a very confusing issue and I Hope you can help me understanding this issue. My goal was to have struct which i can easly iterate over for readability purposes. Unfortunatly I recieved and InvalidCastException and I do not understandt why this happend. I believe the compiler should not have been able to compile it:
Originally
I expected it to work out of the box because I let the interface be implemented over a field of that struct with the help of Reshaper but I recieved a InvalidCastException when running my unittests(luckly there and not in production) trying to iterate over my field.
As I said the problem occured while iterating which means the GetEnumerator() method throws the InvalidCastException. What did I using as underlaying object which I want to iterate over? It is an ConcurrentDictionary (see code example) I found several Questions regarding the IEnumerable Interface.
And as far as i can tell regarding the implemention of that interface have done nothing wrong which is at least visibly obvious.
- IEnumerable.GetEnumerator() and IEnumerable<T>.GetEnumerator()
- Implementing IEnumerable.GetEnumerator() in a wrapper dictionary class
- How would you implement the IEnumerator interface?
public struct test : IEnumerable<(int, string)>
{
public ConcurrentDictionary<string,(int,string)> dictionary ;
public IEnumerator<(int, string)> GetEnumerator()
{
return ((IEnumerable<(int,string)>)dictionary).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<(int,string)>)dictionary).GetEnumerator();
}
}
My understanding was that ConcurrentDictionary Implements IEnumerable and therefore i should be able to simply forward these method calls. At First I thought it might has something todo with invariant/covariant type parameter
- How do i convert a class (which is derived from a generic "base" class) to that generic "base" class
- Casting generic class type to its base class fails
But this does not explain that behaviour to me. So I checked microsofts docu: ConcurrentDictionary and discovered my idiocy: I wanted to Iterate over my Values not the pair of keys and values.
After a lot of thoughts
I cannot get my head around why i am getting an error at Runtime if the types apparently do work out fine at compile time. It should NOT compile in the first place. What am i missing?
I have somekind of idea why if I look at this answer but were speaking about a cast of an IEnumerable with 1 generic type argument vs 2 generic type arguments. Is this difference not enough? Shouldn't this be detectable from the compiler?