5

I just got the following exception, which seems to indicate that Guid is not an object.

Expression of type 'System.Guid' cannot be used for return type 'System.Object'

How is Guid not an object?

And how does the compiler figure this out? There must be something that would allow me to detect at runtime when a type is not an object, if so what would this be?

====================Edit with additional info====================

Expression.Lambda<Func<object>>(SomeExpression)

Where SomeExpression could be a constant value of a Guid, for all that matters.

Alwyn
  • 8,079
  • 12
  • 59
  • 107
  • 2
    This seems related: http://stackoverflow.com/questions/2200209/expression-of-type-system-int32-cannot-be-used-for-return-type-system-object – Tim M. Feb 26 '13 at 08:18
  • Yes it is, but I don't want to cast un necessarily, how would I know if something will work out of the bat? The expression works ok, until I deal with the native/value type of stuff. – Alwyn Feb 26 '13 at 08:20
  • 3
    Your question missing sample code (and preferably CSXXXX error code with link to MSDN, so you can comment on what is not clear). – Alexei Levenkov Feb 26 '13 at 08:20

1 Answers1

17
Expression.Lambda<Func<object>>(SomeExpression)

The problem here is that you are using expression trees incorrectly. Even though the box operation is implicit in C#, it still exists. It is not implicit in expression trees. The following should fix it:

Expression.Lambda<Func<object>>(
    Expression.Convert(SomeExpression, typeof(object))

You could also check SomeExpression.Type.IsValueType to decide whether or not to add this additional explicit conversion.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Marc, the implicit conversion has been working ok, until I deal with Guid. It works fine with my dictionary, list, custom complex class - you name it. I don't think Guid is the only exception, but it's definitely one of them. – Alwyn Feb 26 '13 at 08:25
  • 6
    @Alwyn and everything you mention is a *reference type*. As I said: the box operation must be explicit. `Guid` is a *value type* (a `struct`) – Marc Gravell Feb 26 '13 at 08:26
  • @MarcGravell Gotcha, that'd explain a lot of things, so you need boxing for value types. All reference types get a free pass. – Alwyn Feb 26 '13 at 08:29
  • 1
    @Alwyn yes; the point is that the conversion from (say) `SomeClass` to `object` is value-preserving: it is **exactly** the same value in and out - a trivial no-op. That is very different to a box, which must be represented explicitly. – Marc Gravell Feb 26 '13 at 08:30
  • @MarcGravell Thanks this is the answer I'm looking for, can you give me a hint as to where I can learn a bit more abt some of the terminologies you used? I admit some of them sounds a bit foreign. What's a trivial "no-op" and the difference to a "box"? – Alwyn Feb 26 '13 at 08:32
  • @Alwyn I think this addresses both: http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx – Marc Gravell Feb 26 '13 at 11:48