How to cast implicitly on a reflected method call

人走茶凉 提交于 2019-12-05 09:24:46

问题


I have a class Thing that is implicitly castable from a string. When I call a method with a Thing parameter directly the cast from string to Thing is done correctly.

However if I use reflection to call the same method it throws the exception

System.ArgumentException : Object of type 'System.String' cannot be 
converted to type 'Things.Program+Thing'.

Maybe there is a good reason for this, but I can't figure it out. Does somebody have an idea how to get this working using reflection?

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"});
        }
    }
}

Meta: Please, no discussions why implicit casting or reflection is bad.


回答1:


Found an answer which uses a TypeConverter (as Saeed mentions)
Seems to do the job.

TypeConverter For Implicit Conversion when using reflection




回答2:


The trick is to realize that the compiler creates a special static method called op_Implicit for your implicit conversion operator.

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 });



回答3:


In this specific case you can make the conversion through the array type, that is

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

but that's a kind of "cheating". In general, you cannot expect the Invoke to consider your user-defined implicit operator. This conversion must be inferred compile-time.



来源:https://stackoverflow.com/questions/11544056/how-to-cast-implicitly-on-a-reflected-method-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!