alexc95 alexc95 - 1 month ago 6
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

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
Comments