3

say that I have a C# class like this:

class MyClass<Tkey,Tvalue>{}

How do I get "Tkey" and "Tvalue" from given Type instance? I need the parameter name, not Type.

EDIT My class is of unknown type, so it can be something like

class MyClass2<Ttype>{}

as well

2 Answers 2

2

You first have to use the method GetGenericTypeDefinition() on the Type to get another Type that represents the generic template. Then you can use GetGenericArguments() on that to receive the definition of the original placeholders including their names.

For example:

    class MyClass<Tkey, Tvalue> { };


    private IEnumerable<string> GetTypeParameterNames(Type fType)
    {
        List<string> result = new List<string>();

        if(fType.IsGenericType)
        {
            var lGenericTypeDefinition = fType.GetGenericTypeDefinition();

            foreach(var lGenericArgument in lGenericTypeDefinition.GetGenericArguments())
            {
                result.Add(lGenericArgument.Name);
            }
        }

        return result;
    }

    private void AnalyseObject(object Object)
    {
        if (Object != null)
        {
            var lTypeParameterNames = GetTypeParameterNames(Object.GetType());
            foreach (var name in lTypeParameterNames)
            {
                textBox1.AppendText(name + Environment.NewLine);
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var object1 = new MyClass<string, string>();
        AnalyseObject(object1);

        var object2 = new List<string>();
        AnalyseObject(object2);

        AnalyseObject("SomeString");
    }
Sign up to request clarification or add additional context in comments.

5 Comments

You should probably add a simpler example, without all the unnecessary overhead (you can copy mine, then I'll delete my answer) ;)
Thank you! This is exactly what i needed
I simplified it a little but using LINQ: List<string> genericArguments = T.GetGenericTypeDefinition() .GetGenericArguments().Select(q => q.Name).ToList();
GetGenericTypeDefinition() will return null when the type is no generic, so you should consider this
Thanks, I presume that there is a condition for it.
2

You can use Type.GetGenericArguments to get the Types. From them you can select the name:

IEnumerable<string> genericParameterNames = instance.GetType().GetGenericArguments().Select(t => t.Name);

Edit:

To get the names of the generic arguments, you should have a look at NineBerry's answer. A simplified version of it is this:

IEnumerable<string> genericParameterNames = instance.GetType()
    .GetGenericTypeDefinition()
    .GetGenericArguments()
    .Select(t => t.Name)

5 Comments

This would return the names of the actual types used, not the name of the template arguments
Yes of course but that gives me the Type name e.g. "Int32". I need to get "Tkey"
@czubehead oh, I thought these were just placeholder for the actual names. Have you tried Christos answer?
@czubehead have a look at NineBerry's answer, he explains it very well how to get to those names. I made an edit to my answer to show how to get to those names without the overhead.
This short form using Linq will throw an exception when the type is no Generic, because GetGenericTypeDefinition() will return null

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.