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

第二个问题是相关的。不使用用户定义的转换运算符。在将其传递给SetValue().

于 2010-12-21T16:30:22.640 回答
0

尝试实现IConvertibleConvert将您的实例强制转换为该接口以尝试执行转换。

至于PropertyInfo.SetValue,它获取Set属性的方法。当通过反射 AFAICT 调用此方法时,参数是按类型检查的,而不是隐式转换为正确类型的能力。此强制转换必须在调用之前执行。

于 2010-12-21T16:30:08.337 回答