I recently had to do some reflection in .NET and stumbled upon a strange behavior while comparing generic type definitions.
I had to decide whether a type is an IDictionary<,>
by extracting a Type
object from a LINQ Expression
so I was unable to use the is
operator to decide it. Additionally, I had to ignore the type parameters, in other words, the only thing that was important is whether I was dealing with an IDictionary<,>
of any key/value type.
I started out with the following:
// Just a placeholder, in my code I have no way of knowing that it
// is a Dictionary of string keys and string values or even that it
// is a dictionary at all.
typeof(Dictionary<string, string>)
.GetGenericTypeDefinition()
.GetInterfaces()
.Any(i => i == typeof(IDictionary<,>))
I assumed that since I was reading the interfaces of a generic type definition I would get generic interface definitions. Even more strange is that when I pasted the above code to LINQPad it returned the following:
typeof(IDictionary<TKey,TValue>) // it appears here
typeof(ICollection<KeyValuePair<TKey,TValue>>)
typeof(IEnumerable<KeyValuePair<TKey,TValue>>)
typeof(IEnumerable)
typeof(IDictionary)
typeof(ICollection)
typeof(IReadOnlyDictionary<TKey,TValue>)
typeof(IReadOnlyCollection<KeyValuePair<TKey,TValue>>)
typeof(ISerializable)
typeof(IDeserializationCallback)
Yet for some reason the comparison in the Any
method did not succeed for any of these elements. However, if I get the generic type definitions for the interfaces themselves like so:
typeof(Dictionary<string, string>)
.GetGenericTypeDefinition()
.GetInterfaces()
.Select(i => i.IsGenericType ? i.GetGenericTypeDefinition() : i)
.Any(i => i == typeof(IDictionary<,>))
then it returns true
like it should.
Why is that? Aren't the interfaces returned by the .GetInterfaces()
method when called on a generic type definition generic interface definitions themselves already? If so, what's the explanation that when I inspect the returned interfaces in LINQPad they appear to be generic type definitions?
Aucun commentaire:
Enregistrer un commentaire