Reputation:
Is it possible to determine via reflection whether a field is of generic type or not?
If it is possible, how can it be done?
I suppose my question was not clear enough so I am editing it now.
EDIT:
If a would have a type defined as in following example and DID NOT have instance of Holder<T>
type, but only System.Type
instance retrieved via System.Reflection.Assembly.GetTypes
and System.Reflection.FieldInfo
instance describing field _instance, how can I determine whether _instance field is of generic type
public class Holder<T>
{
private T _instance;
}
Upvotes: 1
Views: 1296
Reputation: 244757
Let me rephrase your question the way I understand it:
I have a generic type and I want to find out whether a certain field type contains (one of) the type argument. How do I do that?
If you want to find out whether a certain type is a generic parameter, you can use the IsGenericParameter
property. That returns true
for T
, but not for List<T>
. If you want that, you have use recursion:
bool ContainsGenericParameter(Type fieldType)
{
return fieldType.IsGenericParameter ||
fieldType.GetGenericArguments().Any(t => ContainsGenericParameter(t));
}
For example, if you have a type like this:
public class Holder<T>
{
private T _t;
private int _int;
private List<T> _listT;
private List<int> _listInt;
}
This query
typeof(Holder<>)
.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
.Select(f => new { f.Name, Generic = ContainsGenericParameter(f.FieldType) })
Will return something like this:
Name Generic
_t True
_int False
_listT True
_listInt False
Upvotes: 0
Reputation: 532445
Using the FieldInfo for the field, you can check the IsGenericType property of the FieldType property if you want to know if the field is a generic type in itself.
var info = type.GetField("myField",BindingFlags.Private);
if (info != null)
{
if (info.FieldType.IsGenericType)
{
Console.WriteLine( "The type of the field is generic" );
}
}
If you what to check if the field is of the type of the generic in a generic class definition, then you'll want to check IsGenericParameter instead.
var info = type.GetField("myField",BindingFlags.Private);
if (info != null)
{
if (info.FieldType.IsGenericParameter)
{
Console.WriteLine( "The type of the field is the generic parameter of the class" );
}
}
You can, of course, combine these. Checking if the field is a generic of the type in a generically defined class, is more problematic, but still can be done. You simply have to check the type parameters of the generic type to see if one of them has IsGenericParameter set. Note the following example is only one level deep; if you want something comprehensive you'll want to define a method and use it recursively.
var info = type.GetField("myField",BindingFlags.Private);
if (info != null)
{
if (info.FieldType.IsGenericType)
{
foreach (var subType in info.FieldType.GetGenericArguments())
{
if (subType.IsGenericParameter)
{
Console.WriteLine( "The type of the field is generic" );
}
}
}
}
Upvotes: 5
Reputation: 62484
Try out
field.GetType().IsGenericType
Gets a value indicating whether the current type is a generic type.
Upvotes: 2