C# неявное приведение "перегрузка" и проблема отражения
У меня проблема со следующим кодом (который компилируется, но вылетает):
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 ответа
Convert.ChangeType()
не использует неявные операторы. Вам нужно иметь свой тип реализации MyBoolean IConvertible
,
Вторая проблема связана. Пользовательские операторы преобразования не используются. Вам нужно будет преобразовать его вручную, прежде чем передать его SetValue()
,
Попробуйте внедрить IConvertible. Convert
преобразует ваш экземпляр в этот интерфейс в попытке выполнить преобразование.
Что касается PropertyInfo.SetValue, он получает Set
метод собственности. Когда этот метод вызывается через отражение, AFAICT, аргументы проверяются по типу, а не по способности неявно приводиться к нужному типу. Этот каст должен быть выполнен до вызова.