3

次のコードに問題があります (コンパイルはできますが、クラッシュします)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    public struct MyBoolean
    {
        public bool Value { get; set; }

        //cast string -> MyBoolean
        public static implicit operator MyBoolean(System.String value)
        {
            return new MyBoolean() { Value = (value[0] == 'J') };
        }

        //cast bool -> MyBoolean
        public static implicit operator MyBoolean(bool value)
        {
            return new MyBoolean() { Value = value };
        }

        //cast MyBoolean -> bool
        public static implicit operator bool(MyBoolean value)
        {
            return value.Value;
        }
    }

    public class Foo
    {
        public MyBoolean TestProp { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyBoolean myBool = true;        //works

            myBool = "N";   //works

            Foo foo = new Foo();
            foo.TestProp = "J";             //works

            PropertyInfo pi = foo.GetType().GetProperty("TestProp");

            var obj = Convert.ChangeType("J", typeof(MyBoolean));       //throws an InvalidCastException

            pi.SetValue(foo, "J", null);       //throws an ArgumentException

        }
    }
}

機能しないステートメントにコメントしました。Convert.ChangeType と PropertyInfo.SetValue が MyBoolean で定義されている「オーバーロードされた」キャスト演算子を使用していないように見える理由を知っている人はいますか?

ところで、ここで他のいくつかのドキュメントを参照してきましたが、問題と完全に一致するものは見つかりませんでした。

よろしくトーマス

4

2 に答える 2

8

Convert.ChangeType()暗黙の演算子を使用しません。MyBoolean タイプを実装する必要がありますIConvertible

2番目の問題は関連しています。ユーザー定義の変換演算子は使用されません。に渡す前に手動で変換する必要がありますSetValue()

于 2010-12-21T16:30:22.640 に答える
0

IConvertibleを実装してみてください。 Convert変換を実行しようとして、インスタンスをそのインターフェイスにキャストします。

PropertyInfo.SetValueSetは、プロパティのメソッドを取得します。このメソッドがリフレクション (AFAICT) を介して呼び出されると、適切な型に暗黙的にキャストする機能ではなく、型によって引数がチェックされます。このキャストは、呼び出す前に実行する必要があります。

于 2010-12-21T16:30:08.337 に答える