Вопрос по reflection, implicit-cast, .net, casting, c# – Как неявно привести к отраженному вызову метода

22

У меня есть классThing который неявно кастуется из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"});
        }
    }
}

Мета:Please, no discussions why implicit casting or reflection is bad.

Неявное приведение невозможно с помощью отражения, но вы можете использоватьTypeConvertor. Saeed Amiri
Если вы действительно хотите это сделать, вы можете создать дерево выражений, которое делает то, что вам нужно, а затем скомпилировать его в метод и выполнить его. Если вы чувствуете, что это работает для вас, я могу добавить это в качестве ответа. Ani
@ChrisSinclair: На самом деле я использую стороннее приложение, которое выполняет рефлексию. Но я думаю, что могу как-то обернуть это. Dio F
аналогичный вопросhere James Barrass
Вдобавок ко всему, я бы поставил на это, потому что (я думаю, и исправьте меня, если я ошибаюсь), что неявное приведение является сахаром синтаксиса для компилятора. То, что фактические вызовы метода приведения связаны во время компиляции. РЕДАКТИРОВАТЬ: Вам нужно иметь какой-то общий способ вызова неявного преобразователя для любого преобразования объекта? Или это особый случай, когда вы захотите нацелить отдельный статический метод или какой-либо другой вызов отражения на заранее определенный метод или, возможно, на специализированный конструктор? Chris Sinclair

Ваш Ответ

3   ответа
10

чтобы понять, что компилятор создает специальный статический метод, называемый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 });
блестящий !!!!!!!!!!!!!
вот еще один аналогичный ответ:stackoverflow.com/a/32025393/2230844
4
Спасибо. Это работает для меня. Dio F
1

массива, то есть

showThingReflected.Invoke(this, new Thing[] {"foo"});

но это своего рода "обман". В общем, вы не можете ожидатьInvoke рассмотреть ваш пользовательскийimplicit operator, Это преобразование должно быть выведено во время компиляции.

Похожие вопросы