alexc95 alexc95 - 10 months ago 43
C# Question

Determining if a field is using a generic parameter

I've been baffled by this and can't seem to get my head around it so hopefully someone can point me in the right direction.

I have a class as follows:

public class Foo<T>
{
public List<T> Data;
}


Now I'm writing code to reflect this class and want to work out a way of determining that the field Data has a generic parameter being used.

My initial approach was to continue going down as many levels as I could and once I hit the IsGenericParameter field set to true I would rather than reflect the type name instead place a "Generic Argument" string there, however I can't seem to get this to work the way I want it to.

I've looked around but every solution I've found seems to point to a dead end with this at the moment.

Answer Source

Here is how to distinguish generic types that rely on class type parameter from generic types that do not. Consider this example:

class Foo<T> {
    public List<T> field1;   // You want this field
    public List<int> field2; // not this field
}

Start by getting generic type definition, and pulling its type arguments:

var g = typeof(Foo<string>).GetGenericTypeDefinition();
var a = g.GetGenericArguments();

This will give you an array with a single type that represents generic type parameter T. Now you can go through all fields, and search for that type among generic type arguments of field types, like this:

foreach (var f in g.GetFields()) {
    var ft = f.FieldType;
    if (!ft.IsGenericType) continue;
    var da = ft.GetGenericArguments();
    if (da.Any(xt => a.Contains(xt))) {
        Console.WriteLine("Field {0} uses generic type parameter", f.Name);
    } else {
        Console.WriteLine("Field {0} does not use generic type parameter", f.Name);
    }
}

This code produces the following output:

Field field1 uses generic type parameter
Field field2 does not use generic type parameter