0

I have a small snipped of code, which checks, wehter an class exists or not.

At first i load all available types:

List<Type> types = new List<Type>(); foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { try { types.AddRange(asm.GetTypes()); } catch (ReflectionTypeLoadException e) { types.AddRange(e.Types.Where(t => t != null)); } } 

Than i concat namespace and class name (which should be checked):

string fullName = ns.Trim() + "." + classToProof.Trim(); 

And in the and, i check wether the class exists:

int found = types.Where(innerItem => innerItem.FullName == fullName).ToList().Count; 

But i have the problem, that if i check generic classes, for example System.Collections.Generic.Dictionary, found is always 0 (should be 1).

Does anyone has an idea, why this happens?

Solution:

List<string> types = new List<string>(); foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { try { types.AddRange(asm.GetTypes().Select(item => (!item.FullName.Contains("`") ? item.FullName : item.FullName.Substring(0, item.FullName.IndexOf("`"))))); } catch (ReflectionTypeLoadException e) { types.AddRange(e.Types.Where(t => t != null).Select(item => (!item.FullName.Contains("`") ? item.FullName : item.FullName.Substring(0, item.FullName.IndexOf("`"))))); } } 

I removed all ` from the full name, and fill a prepared list of strings.

Thank you

1
  • 2
    @MurrayFoxcroft This is absolutely wrong. Commented Jan 9, 2015 at 13:10

2 Answers 2

2

It's probably because generic uses `` with a number that indicates the generic argument count like List`1. And your type name does not have it. To prevent this I would suggest checking the type directly instead of name:

 types.Where(t => t == typeof(Dictionary<,>)) 

Or you can use Substring and IndexOf to get the part before ``

int found = types .Where(t => t.IsGenericType ? t.FullName.Substring(0,t.FullName.IndexOf('`')) == fullName : t.FullName == fullName).ToList().Count; 
Sign up to request clarification or add additional context in comments.

Comments

0

Sorry, but Matias is right, your solution is technically wrong.

The main problem is, that in a namespace types with the same name but with different type args can coexists at the same time. So this is valid:

SomeNameSpace { public class MyType {} // FullName: SomeNameSpace.MyType public class MyType<T> {} // FullName: SomeNameSpace.MyType`1 } 

So, when you try to find System.Collections.Generic.Dictionary, you are actually trying to find a class with name "System.Collections.Generic.Dictionary" but with 0 type arguments. There is no such type in System.Collections.Generic.

If you want to find System.Collections.Generic.Dictionary, that's OK, but the full name of that type is "System.Collections.Generic.Dictionary`2", where the backtick followed by the number 2 means that you talk about a generic type with 2 type args.

Your solution may works, and may solves your concrete problem, but you have to understand that it is technically wrong, because if you removes the backtick-part of the generic typenames, then you actually merges all generic versions of a type into one name. So be aware, and consider using your original code (which is OK), and the correct name of the generic types.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.