meta-generics

  • Thread starter Wiktor Zychla [C# MVP]
  • Start date
W

Wiktor Zychla [C# MVP]

suppose I have a class

class MyContainter {
List<something1> list1;
List<something2> list2;
...
List<somethingn> listn;

othertype1 otherfield1;
...
othertypek otherfieldk;
}

as you can see there are plenty of generics instantiated with different
types.

what I wish is to use reflection to get a list of fields that are of type
List<anything>:

foreach ( FieldInfo fi in typeof(MyContainter).GetFields() )
{
object val = fi.GetValue( TheInstance );

if ( ???? )
{
}
}

what is the best approach to fill the ???? gap so that I have only all these
List<T> fields passed into the if block?

solutions I think about are:
a) matching the type by name - however this is ugly
b) additional attribute on all List<T> fields - seems unnecessary

what I would like is to use pure reflection. something like:

if ( val is List ) { }
if ( val.GetType().IsSubclassOf( ... ) ) { }

however, none of my tries compile since List<> is a generic type and cannot
be used without instantiation of the generic argument. in other words, I
cannot make generics generic on another level of abstraction.

is it possible at all? right now I tend to think that this is impossible.

[I should mention that in the real-life application there are no List<T>
fields but my_own_generic_class<T,K> so any List<T> specific solutions are
not acceptable]

Thanks in advance,
Wiktor Zychla
 
B

Barry Kelly

Wiktor Zychla said:
class MyContainter {
List<something1> list1;
what I wish is to use reflection to get a list of fields that are of type
List<anything>:

foreach ( FieldInfo fi in typeof(MyContainter).GetFields() )
{

Type t = fi.FieldType;

if (t.IsGenericType
&& t.GetGenericTypeDefinition() == typeof(List<>)
&& t.GetGenericArguments()[0] == typeof(anything))
// ...

-- Barry
 
B

Barry Kelly

Barry Kelly said:
Wiktor Zychla said:
class MyContainter {
List<something1> list1;
what I wish is to use reflection to get a list of fields that are of type
List<anything>:

foreach ( FieldInfo fi in typeof(MyContainter).GetFields() )
{

Type t = fi.FieldType;

if (t.IsGenericType
&& t.GetGenericTypeDefinition() == typeof(List<>)
&& t.GetGenericArguments()[0] == typeof(anything))
// ...

I should point out that this is most suitable if you don't already know
that you're dealing with 'anything'. If you do statically know the type,
then you can simply do:

if (fi.FieldType == typeof(List<anything>))

-- Barry
 
G

Greg Young

I am not sure I follow the question.

You have an instance (so you would be dealing with the closed type of the
generic from getvalue)

could you use Type.GetGenericTypeDefinition() to get the open version of the
generic type.then compare this to the type you are after?

If I am understanding you correctly something like this??


public class Foo<T> {
public List<T> bar;
public List<T> bar2;
public int test;
public float test2;
public Foo() {
bar = new List<T>();
bar2 = new List<T>();
}

}

static void CheckForFieldType(object o, Type ToFind) {
foreach (FieldInfo fi in o.GetType().GetFields()) {
if (fi.FieldType.IsGenericType &&
fi.FieldType.GetGenericTypeDefinition() == ToFind) {
Console.WriteLine("Found " + fi.Name);
}
}
}

static void Main(string[] args) {
Foo<int> foo = new Foo<int>();
CheckForFieldType(foo, typeof(List<>));
}


Cheers,

Greg Young
MVP - C#
http://codebetter.com/blogs/gregyoung
 
G

Greg Young

too quick for me .. :( was typing up that quick example

Cheers,

Greg
Barry Kelly said:
Barry Kelly said:
Wiktor Zychla said:
class MyContainter {
List<something1> list1;
what I wish is to use reflection to get a list of fields that are of
type
List<anything>:

foreach ( FieldInfo fi in typeof(MyContainter).GetFields() )
{

Type t = fi.FieldType;

if (t.IsGenericType
&& t.GetGenericTypeDefinition() == typeof(List<>)
&& t.GetGenericArguments()[0] == typeof(anything))
// ...

I should point out that this is most suitable if you don't already know
that you're dealing with 'anything'. If you do statically know the type,
then you can simply do:

if (fi.FieldType == typeof(List<anything>))

-- Barry
 
W

Wiktor Zychla [C# MVP]

too quick for me .. :( was typing up that quick example

big thanks for both of you. what I missed is the possibility of having an
"open" generic type with:

typeof( generictype<> )

this solves my problem completely.

regards,
Wiktor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top