C # неявное приведение "перегрузка" и проблема отражения - PullRequest
3 голосов
/ 21 декабря 2010

У меня проблема со следующим кодом (который компилируется, но падает):

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?

Кстати, я просматривал несколько других документов здесь, но ненайти точное решение проблемы.

С уважением, Томас

Ответы [ 2 ]

8 голосов
/ 21 декабря 2010

Convert.ChangeType() не использует неявные операторы. Вам понадобится ваш тип MyBoolean для реализации IConvertible.

Вторая проблема связана. Пользовательские операторы преобразования не используются. Вам нужно будет преобразовать его вручную перед передачей в SetValue().

0 голосов
/ 21 декабря 2010

Попробуйте реализовать IConvertible .Convert приводит ваш экземпляр к этому интерфейсу в попытке выполнить преобразование.

Что касается PropertyInfo.SetValue, он получает метод свойства Set.Когда этот метод вызывается через отражение, AFAICT, аргументы проверяются по типу, а не по способности неявно приводиться к нужному типу.Этот каст должен быть выполнен до вызова.

...