Take the 2-minute tour ×


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

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

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

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


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


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


Updated my sample code to reflect the whole problem.

share|improve this question
add comment

6 Answers

up vote 4 down vote accepted

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


share|improve this answer
That's what I came up with myself - Extender. Thank you! Will mark this as answer. –  Nikolay R Mar 18 '09 at 17:07
add comment

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.

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:

share|improve this answer
I've added an update which explains why I can not do so. –  Nikolay R Mar 18 '09 at 15:48
add comment

Instead of adding implicit operators, consider implementing IConvertible. You only need to implement the ToInt32 method, the others are meaningless and you can throw the InvalidCastException in the other methods.

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

share|improve this answer
Sorry for not specifying my task entirely. Actually I'm working with Enums and my wrapper is generic<EnumType>. So I can not use IConvertible –  Nikolay R Mar 18 '09 at 16:09
Updated code appropriately –  Nikolay R Mar 18 '09 at 16:25
add comment

or even

var res = new Test(1);
share|improve this answer
add comment

Your local variable res is always of type object; so the line that isn't working is trying to convert an object, that isn't an int, to an int, which can't be done. Same as this fails:

        object d = 5.5d;


Perhaps a pattern that might help is something like this:

        if (res.GetType() == typeof(Test))

It's a very localized solution to your problem, but perhaps it will work for you.

share|improve this answer
Exactly. Is there any way I can control that? –  Nikolay R Mar 18 '09 at 15:48
What do you mean by control? –  Timothy Carter Mar 18 '09 at 15:49
Do some magic in order for this to work :) Console.WriteLine((int)(double)d); - without the double part? –  Nikolay R Mar 18 '09 at 15:51
Pattern, you've suggested may work but I have a hard feeling toward using it. Maybe I'll end up with such code.. –  Nikolay R Mar 18 '09 at 15:56
add comment

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

share|improve this answer
does not work either :( –  Nikolay R Mar 18 '09 at 15:52
add comment

Your Answer


