1

Is there a simple way to obtain the name of a class in c# including template parameters?

I.E

Print( new List<int>{ 100, 1001}); 

Produce one of the following outputs:

List<int>
List<Int32>
System.Collections.Generics.List<System.Int32>

one of the first 2 is preferrable, but Type.FullName is not a viable option. It is ways too verbose.

Too verbose result that is unwanted.

System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=235hosehoue5h]]

Note I'm asking just for a shortcut if it exists. I'm no asking for a full implementation of such feature.

UberFace
  • 445
  • 1
  • 4
  • 14
  • These are not "template parameters", these are "generic type parameters". They are different. Generics in C# are not like templates in C++. – dymanoid Oct 30 '18 at 13:33
  • 1
    `Console.WriteLine(typeof(List))` produces `System.Collections.Generic.List'1[System.Int32]`. Whats wrong with that? – thehennyy Oct 30 '18 at 13:33
  • Missing angle brackets, no good for nested template types for readability => `System.Console.WriteLine(typeof(List,List>>));` prints `System.Collections.Generic.List'1[System.Tuple'2[System.Collections.Generic.List'1[System.Int32],System.Collections.Generic.List'1[System.Char]]]` – UberFace Oct 30 '18 at 13:37
  • 1
    [How about this?](https://stackoverflow.com/a/26429045/106159). Maybe not what I'd class as "simple" though... – Matthew Watson Oct 30 '18 at 13:37
  • @UberFace there is nothing missing, thats just the reflection notation. Maybe its worth asking what do you want to do with these strings? For debug reasons for example it should not matter. – thehennyy Oct 30 '18 at 13:44
  • cool @MatthewWatson then mine answer was duplicate. Thank you – UberFace Oct 30 '18 at 13:52

1 Answers1

1

Create a method to get the class Name.

  1. there is a property in Type class Type.IsGenericType, which mean this type whether is genericType.
  2. use Type.GenericTypeArguments to get all arguments of the generic type the use linq to combine them by ,.
  3. If the class is generic contain generic you can use function recursively to get the name. Thanks for @Eric Lippert point out.

look like this.

public static class ExtensionLib {
    public static string GetClassName(this Type objType)
    {

        string result = objType.Name;
        if (objType.IsGenericType)
        {
            var name = objType.Name.Substring(0, objType.Name.IndexOf('`'));
            var genericTypes = objType.GenericTypeArguments;
            result = $"{name}<{string.Join(",", genericTypes.Select(GetClassName))}>";
        }
        return result;
    }
}

c# online

Input

Console.WriteLine(typeof(List<int>).GetClassName());
Console.WriteLine(typeof(List<List<int>>).GetClassName());  
Console.WriteLine(typeof(Dictionary<List<int>,string>).GetClassName());

Result

List<Int32>
List<List<Int32>>
Dictionary<List<Int32>,String>
D-Shih
  • 44,943
  • 6
  • 31
  • 51
  • 1
    You're so close but not quite right. What happens if you have `List>` with your program? Do you see how to fix it? – Eric Lippert Oct 30 '18 at 14:04
  • @EricLippert Good catch. I edit my answer use function recursive – D-Shih Oct 30 '18 at 14:37
  • 1
    Your fix works but it is needlessly complicated. The recursive call already checks for generic type, so you could just say `genericTypes.Select(x => x.GetClassName())`. In fact, you can make it even shorter than that. You can simply say `genericTypes.Select(GetClassName)` and C# will figure out what you meant. – Eric Lippert Oct 30 '18 at 18:16
  • @EricLippert Wow Thanks new learn. You are so awesome . Could I use your idea in my answer :) – D-Shih Oct 30 '18 at 18:21
  • 1
    Of course, go for it! – Eric Lippert Oct 30 '18 at 18:23