C#, and other .NET languages, have a concept known as Caller Info attributes. When applied to a parameter, the developer isn't responsible for providing the matching argument. Instead the compiler does it for you. Currently C# supports caller info attributes for file name/path, line number, and the name of the calling method or property. With the Caller Expression Attribute proposal, expressions are added to the list.

Consider this pair of assertions:

Assert.IsTrue(x - 7 > 0); Assert.IsTrue(y - 3 > 0);

If the test fails, it would be hard to determine which of the asserts were triggered. You could provide a message for each assertion, but that is tedious and could easily become out of date. What would really be useful is if the expression itself were captured.

public static void IsTrue(bool condition, [CallerArgumentExpression("condition")] string message = null);

In this example, if the developer doesn't explicitly provide a message then the compiler will insert whatever code was used in the condition argument. Essentially the compiler transforms the code to look like this:

Assert.IsTrue(x - 7 > 0, "x - 7 > 0"); Assert.IsTrue(y - 3 > 0, "y - 3 > 0");

Under the proposed design, this capture mechanism will even work with extension methods.

Potential Issues

Three issues were cited with this design.

If null or a string that is not a parameter name (e.g. "notAParameterName") is provided, the compiler will pass in an empty string. People who know how to use decompilers will be able to see some of the source code at call sites for methods marked with this attribute. This may be undesirable/unexpected for closed-source software. Although this is not a flaw in the feature itself, a source of concern may be that there exists a Debug.Assert API today that only takes a bool. Even if the overload taking a message had its second parameter marked with this attribute and made optional, the compiler would still pick the no-message one in overload resolution. Therefore, the no-message overload would have to be removed to take advantage of this feature, which would be a binary (although not source) breaking change.

Status

Currently the Caller Expression Attribute is listed on the C# 8 roadmap with the status "Prototype".