Let's say I have a method:
public void ExampleMethod<T>(T x) where T : struct // or new()
{
// example usage, similar to what's actually happening
var z = (T)Enum.Parse(typeof(T), privateFieldOfTypeString);
// do something depending on values of x and z
// possibly using other methods that require them being enums
// or in case of the new() constraint:
// var t = new T() and do something together with x
}
and I want to use it as follows:
public void CallerMethod<S>(S y)
{
if (typeof(S).IsEnum) // or some other invariant meaning that `S` is "new()able"
{
ExampleMethod(y); // won't compile
}
}
So, during run-time I know that S
satisfies the constraint for ExampleMethod<T>
. I know it's possible to call it using reflection, something along the lines of:
this
.GetType()
.GetMethod(nameof(ExampleMethod<object>))
.MakeGenericMethod(typeof(S))
.Invoke(this, new object[] { y });
Is it possible without reflection?
Note: this is a simplified code from a real-life example and obviously I have no control over the signatures of these methods, hence the answers "add the constraint to CallerMethod
" and "remove the constraint from ExampleMethod
" are invalid.
Yes, the whole thing should be redesigned so the whole problem wouldn't appear at all. But as often in real-life "the whole thing" is too big, too coupled and too risky to rewrite. Some requirements have changed in an unexpected way - hence the apparent code smell, which I'm trying to minimize by hiding it in a single nasty-looking place.
You could use
dynamic
: