4

我有一个伪装成 int 的类,所以它重载了各种运算符;

public class MyId
{
    int value;
    public virtual int Value
    {
        get { return this.value; }
        set { this.value = value; }
    }

    public MyId(int value)
    {
        this.value = value;
    }


    public static implicit operator MyId(int rhs)
    {
        return new MyId(rhs);
    }

    public static implicit operator int(MyId rhs)
    {
        return rhs.Value;
    }


}

但是,当我使用类似的代码时

PropertyInfo.SetValue(myObj, 13, null)
OR
MyId myId = 13;
int x = Convert.ToInt32(myId);
IConvertible iConvertible = x as IConvertible;
iConvertible.ToType(typeof(MyId), CultureInfo.CurrentCulture);

我得到无效的演员表。我很困惑,这两个调用似乎都试图在 int 上调用 convert ,这将失败,因为 int 不理解 MyId 类型(即使所有赋值运算符都在那里)。对此有任何解决方法的想法,我确定我一定错过了一些愚蠢的东西吗?

4

1 回答 1

4

隐式转换是 C# 构造,不能通过反射获得。此外,通过反射设置字段或属性意味着您必须预先提供适当的类型。您可以尝试通过使用自定义 TypeConverter(或其他一些自定义转换方式)来帮助在运行时在使用反射之前转换您的类型来规避这种情况。这是 TypeConverter 实现的粗略示例。

public class MyIdTypeConverter : TypeConverter
{                
    public override object ConvertFrom(ITypeDescriptorContext context,
                                       System.Globalization.CultureInfo culture,
                                       object value)
    {   
        if (value is int)
            return new MyId((int)value);
        else if (value is MyId)
            return value;
        return base.ConvertFrom(context, culture, value);
    }               
}

这是我们试图设置Custom属性的类型。

public class Container
{
    [TypeConverter(typeof(MyIdTypeConverter))]
    public MyId Custom { get; set; }                
}

调用它的代码必须检查属性并提前执行转换,然后才能调用SetValue.

var instance = new Container();
var type = typeof(Container);
var property = type.GetProperty("Custom");

var descriptor = TypeDescriptor.GetProperties(instance)["Custom"];
var converter = descriptor.Converter;                
property.SetValue(instance, converter.ConvertFrom(15), null);
于 2012-05-21T23:08:23.277 回答