csharplang/meetings/2017/LDM-2017-01-17.md
2017-04-04 15:17:33 -07:00

2.7 KiB

C# Language Design Notes for Jan 17, 2017

Agenda

A few C# 7.0 issues to review.

  1. Constant pattern semantics: which equality exactly?
  2. Extension methods on tuples: should tuple conversions apply?

Constant pattern semantics

Issue #16513 proposes a change to the semantics of constant patterns in is expressions. For the code

e is 42

We currently generate the call object.Equals(e, 42) (or equivalent code), but we should instead generate object.Equals(42, e).

The implementation of object.Equals does a few reference equality and null checks, but otherwise delegates to the instance method Equals of its first argument. So with the current semantics the above would call e.Equals(42), whereas in the proposal we would call 42.Equals(e).

The issue lists several good reasons, and we can add more to the list:

  • The constant pattern isn't very constant, when it's behavior is determined by the non-constant operand!
  • Optimization opportunities are few when we cannot depend on known behavior of calling c.Equals on a constant value.
  • Intuitively, the pattern should do the testing, not the object being tested
  • Calling a method on the expression could cause side effects!
  • The difference from switch semantics is jarring
  • Switching would preserve the nice property of is expressions today that it only returns true if the left operand is implicitly convertible to the (type of the) right.

There really is no downside to this, other than the little bit of work it requires to implement it.

Conclusion

Do it.

Extension methods on tuples

Issue #16159 laments the facts that extension methods only apply to tuples if the tuple types match exactly. This is because extension methods currently only apply if there is an identity, reference or boxing conversion from the receiver to the type of the extension method's first parameter.

The spirit of this rule is that if it applies to a type or its bases or interfaces, it will work. We agree that it feels like it should also work for tuples - at least "sometimes". We cannot make it just always work for tuple conversions, though, since they may recursively apply all kinds of conversions, including user defined conversions.

We could check recursively through the tuple type for "the right kind of conversion". Compiler-wise this is a localized and low-risk change. It makes tuples compose well with extension methods. It's another place where things should "distribute over the elements" of the tuple.

This is a now-or-never kind of change. It would be a breaking change to add later.

Conclusion

Try to do it now if at all possible.