4

I have a class that pretends to be an int, so it has overloaded the various operators;

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;
    }


}

However, when I use code like

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);

I get invalid cast. I'm puzzled, both calls seem to attempt to call convert on the int which will fail because int doesn't understand the type MyId (even though all the assignment operators are there). Any ideas of a workaround for this, I'm sure I must be missing something stupid?

6
  • 2
    Have you tried implementing IConvertible? Commented May 21, 2012 at 16:39
  • What you have described so far is exactly what Int32 does... provides an object box around a native 32-bit integer. I assume there's more to your use case, but if not, just use Int32. Commented May 21, 2012 at 16:41
  • 1
    I've fully implemented icovertable on myid but it looks like it's calling it on int32 so I can't affect that. Commented May 21, 2012 at 21:56
  • If you're suggesting use an int rather than myid then no, as you suggest it's doing a lot more than pretending to be an int. Commented May 21, 2012 at 21:58
  • Just to add, the following works fine, myid = 13 Commented May 21, 2012 at 21:59

1 Answer 1

4

Implicit conversions are a C# construct and are not available through reflection. Additionally, setting a field or property through reflection means that you must provide the appropriate type up front. You can attempt to circumvent this by using a custom TypeConverter (or some other means of custom conversion) to help convert your types at runtime prior to using reflection. Here's a rough example of a TypeConverter implementation.

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);
    }               
}

Here's the type that we would be trying to set the Custom property on.

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

The code to call it would have to check the attribute and perform the conversion ahead of time, after which it could call 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);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, it's starting to look like a bit of an overhead but that's a good solution, thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.