I'd happily be proven wrong by another answer, but I don't think this is possible without resorting even more to reflection. See further below for the reason that makes me suspect this. See end of the answer for a reflection-based solution.
Practical suggestion: I would simply drop the constraint on your FooStruct
and FooClass
methods, and additionally:
either make them non-generic and accept an argument of type object
(which is what val
is declared as, anyway). There's no advantage to having these methods be generic if they are only ever passed object
s;
or cast val
from object
to T
before invoking FooStruct
/ FooClass
.
Why does it seem impossible to do what you're asking? You are trying to convert an expression that is statically typed object
(namely val
) into something that is statically typed <T> where T : struct
or <T> where T : class
(in order to call the respective extension method on such a T
). That is, you are trying to dynamically introduce a new type variable inside your foreach
loop. Unfortunately, the only way to introduce a type variable is to declare it in advance, i.e. as some generic type parameter T
in the method's signature; and then it is not the code inside your method that gets to choose what actual type it stands for—it's the calling code that determines T
.
Reflection-based solution:
// determine which method ought to be called based on `val`'s run-time type.
// (for C# 6 and later, use the `nameof` operator instead of hard-coding method names)
Type type = val.GetType();
string fooName = type.IsValueType ? "FooStruct" : "FooClass";
// bind to the generic method and supply the type argument for it:
// (I'm assuming that your extension methods are defined in `FooMethodsClass`.)
MethodInfo fooOpen = typeof(FooMethodsClass).GetMethod(fooName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo foo = fooOpen.MakeGenericMethod(new Type[] { type });
// invoke the generic (extension) method with `val` as the `this` argument:
foo.Invoke(null, new object[] { val });