12
votes

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

1
"reference conversion to T0 AND T0 has an identity conversion to T.".. sounds like there is a difference.Lews Therin
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
@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
I won't pretend to understand this shiz. But I just found this.. might help: stackoverflow.com/questions/3736789/…Lews Therin
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

1 Answers

12
votes

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.