Я бы с радостью доказал свою несостоятельность по другому ответу, но я не думаю, что это возможно, даже не прибегая к размышлениям. См. Ниже ниже причину, по которой я подозреваю это. См. Конец ответа для решения на основе отражения.
Практическое предложение: я просто уронить ограничение на ваших FooStruct
и FooClass
методов, и дополнительно:
либо сделать их нетипичными и принять аргумент типа object
(что val
объявляется как, во всяком случае). Нет никакого преимущества в том, чтобы эти методы были общими, если они только когда-либо прошли object
s;
или литой val
от object
к T
перед вызовом FooStruct
/FooClass
.
Почему это невозможно сделать, что вы просите? Вы пытаетесь преобразовать выражение, которое статически напечатано object
(а именно val
) во что-то, что статически напечатано <T> where T : struct
или <T> where T : class
(для вызова соответствующего метода расширения на таком T
). То есть вы пытаетесь динамически вводить новую переменную типа внутри цикла foreach
. К сожалению, единственный способ ввести переменную типа состоит в том, чтобы объявить ее заранее, то есть как некоторый общий тип параметра T
в сигнатуре метода; и тогда это не код внутри ваш метод, который позволяет выбрать, какой фактический тип он обозначает —, это , вызывающий код, определяющий T
.
Отражение на основе раствора:
// 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 });
Видя, как вы используете GetType(), вы уже с помощью отражения:) – Carra
У нас недостаточно информации, так как вы используете только отражение в вашем примере. Пожалуйста, объясните, в чем проблема. –
Вы имеете в виду: возможно ли задание объекта, содержащего экземпляр structed boxed? Вы хотите вызвать метод в переменной 'val' правильно? – helb