views:

196

answers:

4

In the DLR's LINQ Expressions, what is the difference between this:

Expression.Convert(SomeVariableExpression, typeof(T));

and this:

Expression.Unbox(SomeVariableExpression, typeof(T));

The documentation on this seems a bit sketchy.

And more to the point, which one of these is equivalent to this C# code:

(ClassA)InstanceOfClassB

Where ClassB has an implicit or explicit operator to cast to ClassA?

+2  A: 

Well the main difference is that Epression.Unbox is only needed for explicit unboxing of a value type off the heap. Expression.Convert is the method you would want to use to hook into a user-defined conversion (whether implicit or explicit).

See Expression.Convert:

If either expression.Type or type is a user-defined type that defines an implicit or explicit conversion operator, the MethodInfo that represents that operator is the implementing method.

and also:

If either expression.Type or type is a reference type and an explicit boxing, unboxing, or reference conversion exists from expression.Type to type, the implementing method is null.

Andrew Hare
+1  A: 

Expression.Convert is the equivalent of doing a cast.

Jacob B
Unboxing is the process of getting a value type that has been previously boxed (in other words the value from the stack is copied to the heap and a reference to the new object is pushed onto the stack).
Andrew Hare
+1  A: 

In general, boxing takes a value type and wraps it in an object. Unboxing does the reverse. You can think of this as boxing takes a register or stack value and puts it on the heap, returning a pointer to that value. Unboxing takes an object on the heap and puts it into a register or stack frame. The underlying datatype stays the same.

Convert changes one datatype into another.

James Hugard
+2  A: 

The important thing Unbox is that it gives you the address of the boxed value. This ensures that you can call a method on the unboxed value. If that method mutates the value type then it's mutating the boxed version instead of a new copy. If you merely did Convert then you'd actually have made a copy of the boxed value type and then calling a method on it would mutate the copy and not the original value.

Dino Viehland