12

In 6.1.6. of the C# language specification, there is:

The implicit reference conversions are:

(...)
From any reference-type to a reference-type T if it has an implicit identity or reference conversion to a reference-type T0 and T0 has an identity conversion to T.

Why don't they say instead, more simply:

From any reference-type to a reference-type T if it has an implicit identity or reference conversion to T.

Is there any factual difference?

EDIT: I realized I mistyped the specification and the error could potentially be significant for the question (the specification says "The implicit reference conversion are" rather than "An implicit conversion exists")

Petr Hudeček
  • 1,623
  • 19
  • 30
  • 2
    "reference conversion to T0 AND T0 has an identity conversion to T.".. sounds like there is a difference. – Lews Therin Jan 05 '14 at 15:30
  • I think the last part could be important. As type `T` could implicitly convert to type `U` due to its implicit identity or reference conversion to `U`. However `U` *may not* necessarily have an identity conversion to `U`. It doesn't mention `U` having a reference conversion to `T` though... confuzzed. – Lews Therin Jan 05 '14 at 15:37
  • @LewsTherin It sounds like that, sure, but what is it? I'm confused why the "middle-man" T0 is necessary. By my reading, all types have an identity conversion to themselves and no type has an identity conversion to any other type. – Petr Hudeček Jan 05 '14 at 15:41
  • I won't pretend to understand this shiz. But I just found this.. might help: http://stackoverflow.com/questions/3736789/question-regarding-implicit-conversions-in-the-c-sharp-language-specification – Lews Therin Jan 05 '14 at 15:47
  • I think you mistake the *and*, it should be (from S to T0) AND (from T0 to T). So if S can be converted to T0 and T0 to T then S can be converted to T. – Dirk Jan 05 '14 at 15:48
  • @Dirk Like transitivity? if a is b and b is c then a is c? – Lews Therin Jan 05 '14 at 15:50
  • @Lews Therin that's how I understand it, except that is slightly more complicated because from S to T0 is a reference conversion and from T0 to T an indentity conversion. – Dirk Jan 05 '14 at 15:54
  • S to T0 can be an identity or reference conversion.. so I guess the confusion starts when S to T0 has no identity conversion but only reference conversion. Maybe the spec should first define what "identity conversion" and "reference conversion" is. – Lews Therin Jan 05 '14 at 15:58
  • I think you need it to convert `Derived` to `Base`. – Hans Passant Jan 05 '14 at 16:06
  • @LewsTherin: I think you'll find that the spec does define both those things. – Eric Lippert Jan 05 '14 at 16:15
  • @EricLippert I was able to find one for "reference conversion" not identity conversion though. – Lews Therin Jan 05 '14 at 16:17
  • @LewsTherin: Consider looking in the table of contents. – Eric Lippert Jan 05 '14 at 16:20
  • @EricLippert I did find that. But it is over complicated. "An identity conversion converts from any type to the same type. This conversion exists such that an entity that already has a required type can be said to be convertible to that type." "Same type", "that type" means little to me. I like your explanation better though. – Lews Therin Jan 05 '14 at 16:25
  • @LewsTherin: The specification does not even define "type". It's not intended to be a formal description of the type system; you won't find any Hoare logic in the specification. – Eric Lippert Jan 05 '14 at 16:32

1 Answers1

12

If an identity conversion exists from S to T, must it be that S and T are same type?

The oddity you've discovered in the spec arose as a result of adding dynamic to the language in C# 4.0. At runtime there is no such thing as dynamic; rather, dynamic is just a type that means "I'm really object; please defer analysis of this portion of the program until runtime".

Therefore there is an identity conversion between, say, List<object> and List<dynamic>. From the C# compiler's perspective they are different types because myList[0].Frob() would give an error for the former but not the latter. But from the runtime's perspective they are identical. Therefore the C# language classifies the conversion from one to the other as an identity conversion. At compile time the types can be different for the purposes of the C# language, but from the runtime's perspective they will be identical.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067