C #: How can I use an implicit operator statement during object type conversion?

Hi!

Here is my case: I have some type of value that is wrapped in another type with the corresponding implicit converters. If I pass the wrapped type to an object and then try to get the original value, I can only do this in two-step mode. If this code is simplified, the following code:

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 fine. The second is unsuccessful.

Is there a way to change this behavior and make it work without a double cast?

UPDATE 1

I have to use the object for the cast value (in a real application I need to set the ComboBox.SelectedItem property, and I don’t want to add an additional property to the ComboBox, because I have to change the user interface 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.

+4
source share
6 answers

If you want to simplify casting and don't care about performance, create an 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 }); } 

Using

 Console.WriteLine(res.To<MyEnum>()); 
+4
source

Do not use object in this way. Instead, write your first line as follows:

 Test res = new Test(1); 

If you must first have it in an object, remember that the whole compiler knows about it at this moment, that it is an object, and nothing more. As a programmer, you have additional information about what you expect from this object, but for the compiler to use this information, you must put it somewhere in your code.

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

+6
source

Instead of adding implicit statements, consider using IConvertible . You only need to implement the ToInt32 method, others are pointless, and you can throw an InvalidCastException in other methods.

After that, you can use Convert.ToInt32 () to convert your object in one step.

+2
source

or even

 var res = new Test(1); 
+1
source

The local variable res always has an object type; therefore, a line that does not work tries to convert an object that is not an int to an int that cannot be executed. Same as this:

  object d = 5.5d; Console.WriteLine((int)d); 

EDIT:

Perhaps a template that might help looks something like this:

  if (res.GetType() == typeof(Test)) { Console.WriteLine((int)(Test)res); } else { Console.WriteLine((int)res); } 

This is a very localized solution to your problem, but perhaps it will work for you.

+1
source

While the error is due to the res type of the type object, I would make the Test-> int statement explicit ...

0
source

All Articles