23

Thingから暗黙的にキャスト可能なクラスがありstringます。パラメータを使用してメソッドを直接呼び出すと、toThingからのキャストが正しく実行されます。stringThing

ただし、リフレクションを使用して同じメソッドを呼び出すと、例外がスローされます

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

メタ:暗黙のキャストやリフレクションが悪い理由については議論しないでください。

4

3 に答える 3

17

秘訣は、コンパイラが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 });
于 2012-07-19T15:15:09.213 に答える
5

TypeConverterを使用する答えを見つけました(Saeedが言及している
ように)仕事をしているようです。

リフレクションを使用する場合の暗黙的な変換用のTypeConverter

于 2012-07-18T15:33:55.340 に答える
1

この特定のケースでは、配列型を介して変換を行うことができます。

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

しかし、それは一種の「浮気」です。Invoke一般に、がユーザー定義を考慮することを期待することはできませんimplicit operator。この変換は、コンパイル時に推測される必要があります。

于 2012-07-18T15:30:00.633 に答える