Ответ 1
Нашел ответ, в котором используется TypeConverter (как упоминает Саид)
Кажется, чтобы выполнить эту работу.
TypeConverter для неявного преобразования при использовании отражения
У меня есть класс Thing
, который неявно может быть спрятан от a string
. Когда я вызываю метод с параметром Thing
напрямую, выполняется отличное от string
до Thing
.
Однако, если я использую отражение для вызова того же метода, он генерирует исключение
System.ArgumentException : Object of type 'System.String' cannot be
converted to type 'Things.Program+Thing'.
Может быть, для этого есть веская причина, но я не могу понять это. Есть ли у кого-нибудь идея, как это сделать, используя отражение?
namespace Things
{
class Program
{
public class Thing
{
public string Some;
public static implicit operator Thing(string s)
{
return new Thing {Some = s};
}
}
public void showThing(Thing t)
{
Console.WriteLine("Some = " + t.Some);
}
public void Main()
{
showThing("foo");
MethodInfo showThingReflected = GetType().GetMethod("showThing");
showThingReflected.Invoke(this, new dynamic[] {"foo"});
}
}
}
Мета: Пожалуйста, не обсуждайте, почему неявное литье или отражение плохо.
Нашел ответ, в котором используется TypeConverter (как упоминает Саид)
Кажется, чтобы выполнить эту работу.
TypeConverter для неявного преобразования при использовании отражения
Трюк заключается в том, чтобы понять, что компилятор создает специальный статический метод под названием op_Implicit
для вашего оператора неявного преобразования.
object arg = "foo";
// Program.showThing(Thing t)
var showThingReflected = GetType().GetMethod("showThing");
// typeof(Thing)
var paramType = showThingReflected.GetParameters()
.Single()
.ParameterType;
// Thing.implicit operator Thing(string s)
var converter = paramType.GetMethod("op_Implicit", new[] { arg.GetType() });
if (converter != null)
arg = converter.Invoke(null, new[] { arg }); // Converter exists: arg = (Thing)"foo";
// showThing(arg)
showThingReflected.Invoke(this, new[] { arg });
В этом конкретном случае вы можете выполнить преобразование через тип массива, то есть
showThingReflected.Invoke(this, new Thing[] {"foo"});
но это своего рода "обман". В общем случае вы не можете ожидать, что Invoke
рассмотрит ваш пользовательский implicit operator
. Это преобразование должно быть выведенным временем компиляции.