So this has been discussed on S.O. before however I don’t think I have really ever seen an explanation of why this happens, nor can I seem to glean how this is useful to the average developer trying to use reflection in their code.
So check this bit of code out.
var fields = typeof(Person).GetFields(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Instance);
If I have a List<int> in my Person object then I will get back a field who’s reflection “Name” is set to List`1, or if I had a dictionary it would be Dictionary`2. On the surface it appears this makes it hard to work with, I can’t say the following
foreach (var fieldInfo in fields.Where(fieldInfo => fieldInfo.FieldType == typeof(List<int>)))
{
//Do something.
}
The reason this comes up is because I found the following in a project I am currently am working on.
//Initialize collections
FieldInfo[] properties = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Instance);
foreach (FieldInfo f in properties)
{
if (f.FieldType.Name == "IList`1" && f.GetValue(obj) == null)
{
object value = Container.Resolve(f.FieldType);
f.SetValue(obj, value);
}
}
Then in the configuration for unity I see this happiness
<alias alias="IList`1" type="System.Collections.Generic.IList`1, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
I don’t really know that I know this is bad? Is it? It works of course, but even if this is OK (which causes my suspicious-code-dar to go off) my original question remains. What good does the dimension information about the generic do us as programmers?
When you’re dealing with types that are known at compile time, you shouldn’t ever need to deal with the
Nameof theType, so names such asThing`nshouldn’t be an issue.I’m not sure what’s happening in your first example, as when I do this:
and this:
I get what I would expect, namely
In the code sample you give, again the types are known at compile time; better than what you have shown would be
You know what a
IList<int>is; you can useIsAssignableFromor==as appropriate.(If you get confused by
IsAssignableFrom, as I always do, remember this:if (a is b)is the same test asif (typeof(b).IsAssignableFrom(a.getType())). The order swaps round.