roslyn: Proposal: Make "throw expression" an expression form

The spec has been moved

The spec for the proposed throw expression has been moved to https://github.com/dotnet/roslyn/blob/future/docs/features/patterns.md

Below is a snapshot that may be out of date.


I propose to extend the set of expression forms to include

throw-expression:       throw null-coalescing-expression null-coalescing-expression:       throw-expression

The type rules are as follows:

A throw-expression has no type. A throw-expression is convertible to every type by an implicit conversion.

The flow-analysis rules are as follows:

For every variable v,

  • v is definitely assigned before the null-coalescing-expression of a throw-expression iff it is definitely assigned before the throw-expression.
  • v is definitely assigned after throw-expression.

A throw expression is allowed in only the following contexts:

  • As the second operand of a ternary conditional operator ?:
  • As the third operand of a ternary conditional operator ?:
  • As the second operand of a null coalescing operator ??
  • After the colon of a match section (see #5154)
  • As the body of an expression-bodied lambda or method.

This proposal is intended to facilitate a move toward expression-oriented programming, adding convenience in a number of scenarios. For example

An expression-bodied method may now throw

void M() => throw new NotImplementedException();

A conditional expression may throw on one branch:

var foo = term.HasValue ? term.Value.Foo() : throw new ArgumentException("term");

I am proposing this to facilitate a proposal (#5154) for an expression form of a pattern-matching switch, where one may want to throw in some branch.

This is related to #59 and #1226.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 19 (9 by maintainers)

Commits related to this issue

Most upvoted comments

I like this solution, but It can be implemented today with this nice trick:

public static T Throw<T>(this Exception ex)
{
     throw ex;
}

And used like:

var foo = term.HasValue ? DateTime.Now : new ArgumentException("term").Throw<DateTime>();

Just my 2 cents…