Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#: How can I use implicit cast operator during object to type conversion?

Tags:

c#

enums

casting

HI!

Here is my case: I have some value type which is wrapped into another type with appropriate implicit converters. If I cast wrapped type to an object and then try to get original value I can do that in two-step cast only. If simplified my code is as follows:

public enum MyEnum : int
    {
        First,
        Second
    }


    public class Test<T>
    {
        public Test(T val)
        {
            Value = val;
        }

        private T Value { get; set; }


        public static implicit operator T(Test<T> m)
        {
            return m.Value;
        }

        public static implicit operator Test<T>(T m)
        {
            var res = new Test<T>(m);
            return res;
        }
    }


    static void Main()
    {
        object res = new Test<MyEnum>(MyEnum.First);
        Console.WriteLine((MyEnum)(Test<MyEnum>)res);
        Console.WriteLine((MyEnum)res);
    }

First "Console.WriteLine" works OK. Second one fails.

Is there any way I can modify this behavior and get it working without double casting?

UPDATE 1

I must use object to value cast (in real application I have to cast ComboBox.SelectedItem property and I do not want to add extra property to ComboBox, because I'll have to change my UI interaction code everywhere).

UPDATE 2

Implicit conversions to and from System.Object are not allowed.

UPDATE 3

Updated my sample code to reflect the whole problem.

like image 607
Nikolay R Avatar asked Dec 10 '22 21:12

Nikolay R


2 Answers

Don't use object that way. Write your first line like this instead:

Test res = new Test(1);

If you must have it in an object first, remember that all the compiler knows about it at this point is that it's an object, and nothing more. You, as the programmer, have additional information about what you expect this object to be, but for the compiler to take advantage of that information you have to put it into your code somewhere.

Update:
I'm glad I was able to find this again, because this almost-very-timely article by Eric Lippert, who works on the C# language design, went up this morning and explains the problem in depth:
http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx

like image 146
Joel Coehoorn Avatar answered Jan 30 '23 12:01

Joel Coehoorn


If you want to simplify casting and not care performance effect, then create extension method.

public static T To<T>(this object obj) {
    Type type = obj.GetType();
    MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
    MethodInfo method = methods.FirstOrDefault(mi => (mi.Name == "op_Implicit" || mi.Name == "op_Explicit") && mi.ReturnType == typeof(T));
    if (method == null)
        throw new ArgumentException();
    return (T)method.Invoke(null, new[] { obj });
}

Usage

Console.WriteLine(res.To<MyEnum>());
like image 27
Chaowlert Chaisrichalermpol Avatar answered Jan 30 '23 11:01

Chaowlert Chaisrichalermpol