2

I'm trying to get the type parameter's name (ClassName<TypeParameterName>) of geneic class from the class type.

for example something like this:

class MyClass<Type1>
{
    public Type data;
}
static void Main()
{
    Console.WriteLine(typeof(MyClass<int>).GetTypeParameterName());
    //prints: Type1
}

I searched a lot and didn't find anything about how to do this. the only thing I thought of was using StreamReader and read the whole .cs file and find the type there in the text. But is there any faster/cleaner way to do this?

Note: I'm not trying to get the type of Type1 I'm trying to get the string "Type1".

  • Possible duplicate of [How do I get the type name of a generic type argument?](https://stackoverflow.com/questions/2581642/how-do-i-get-the-type-name-of-a-generic-type-argument) – Lucifer May 25 '18 at 10:40
  • @Lucifer No it's not. I'm not trying to get the type of T i'm trying to get the string "T" – Tᴏᴍᴇʀ Wᴏʟʙᴇʀɢ May 25 '18 at 10:42
  • 1
    Why would you even want to do that? It's just kind of placeholder name, you can't do much by that name. – SᴇM May 25 '18 at 10:43
  • 1
    Didn´t you write in the code, thatn it already prints out `"Type1"`. So what do you want instead? The `"int"`? – MakePeaceGreatAgain May 25 '18 at 10:48
  • 1
    @SeM we learn c# in my school and my school has **a lot** of rules about how you should write classes and if you don't write it like this they don't read it. And I'm trying to create a method that gets a class type and returns what you need to change about the class (if you break one of the rules). Sorry for bad English – Tᴏᴍᴇʀ Wᴏʟʙᴇʀɢ May 25 '18 at 10:51
  • @HimBromBeere I guess it **should** do that, but does not - or do you know of a method `GetTypeParameterName()` on `Type`? – Toxantron May 25 '18 at 10:52
  • 1
    @TᴏᴍᴇʀWᴏʟʙᴇʀɢ they should give you an A just for implementing that solution. Not many students would be able to use reflection and meta-programming to implement a rule checker :-) – Toxantron May 25 '18 at 10:53
  • FYI: For the future you could also use tools like ReSharper and put your schools rule-set in there. It can do the same with a pretty UI. – Toxantron May 25 '18 at 10:57
  • @TᴏᴍᴇʀWᴏʟʙᴇʀɢ FYI2: Well, if you want to validate only your code, you can create snippets inside visual studio, for example `gclass` for generic class, and create base code the way you like. – SᴇM May 25 '18 at 11:01
  • @Toxantron I don't know what meta-programming means but I agree ;) – Tᴏᴍᴇʀ Wᴏʟʙᴇʀɢ May 25 '18 at 11:33
  • @SeM does it work only in Visual Studio? Because i only have notepad++. – Tᴏᴍᴇʀ Wᴏʟʙᴇʀɢ May 25 '18 at 12:19
  • @TᴏᴍᴇʀWᴏʟʙᴇʀɢ Yeap, it's in VS. – SᴇM May 25 '18 at 12:21

3 Answers3

3

In your example, you already set the generic type parameter to int, so you won't get your Type1.

Try this:

class MyClass<Type1>
{
    public Type data;
}
static void Main()
{
    Console.WriteLine(typeof(MyClass<>).GetGenericArguments()[0].Name);
    //prints: Type1
}
tur
  • 328
  • 1
  • 8
0

Try the following:

       .
       .
       .
      //Create and object of the relevant generic class
       ClassName<string> d = new ClassName<string>();

       // Get a Type object representing the constructed type.
       Type constructed = d.GetType();

       Type generic = constructed.GetGenericTypeDefinition();
       DisplayTypeInfo(generic);
    }

    private static void DisplayTypeInfo(Type t)
    {
        Console.WriteLine("\r\n{0}", t);
        Console.WriteLine("\tIs this a generic type definition? {0}", 
            t.IsGenericTypeDefinition);
        Console.WriteLine("\tIs it a generic type? {0}", 
            t.IsGenericType);
        Type[] typeArguments = t.GetGenericArguments();
        Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length);
        foreach (Type tParam in typeArguments)
        {
            Console.WriteLine("\t\t{0}", tParam);
        }
    }

Source: https://msdn.microsoft.com/en-us/library/system.type.getgenerictypedefinition(v=vs.110).aspx

Mikaal Anwar
  • 1,720
  • 10
  • 21
0

I say let's make it a nice extension method that works for all types, which seems to fit your scenario of code analysis.

static class TypeExtensions {
    public static IEnumerable<string> GetGenericTypeParameterNames(this Type type) {
        if (type.IsGenericTypeDefinition) {
            return type.GetGenericArguments().Select(t => t.Name);
        } else if (type.IsGenericType) {
            return type.GetGenericTypeDefinition().GetGenericArguments().Select(t => t.Name);
        } else {
            return Enumerable.Empty<string>();
        }
    }
}

Now typeof(MyClass<int>).GetGenericTypeParameterNames() is Type1, while typeof(int).GetGenericTypeParameterNames() is empty. Use .Where() with whatever criterion you please to weed out "bad" names.

Jeroen Mostert
  • 27,176
  • 2
  • 52
  • 85