Local functions were introduced in C# 7.0 but could not have attributes applied to them. This meant you could not use compiler-recognized attributes like [Conditional], [NotNullWhen], or [DoesNotReturn] on local functions.
C# 9.0 allows attributes on local functions and their parameters, bringing them to parity with regular methods.
Code
C#
static void Validate(string name)
{
[DoesNotReturn]
static void ThrowHelperError(string paramName)
{
throw new ArgumentNullException(paramName);
}
if (name is null)
ThrowHelperError(nameof(name));
}
static bool TryParse(string input, [NotNullWhen(true)] out MyType? result)
{
[return: NotNullIfNotNull(nameof(input))]
static MyType? ParseCore(string s) => new MyType(s);
result = input is not null ? ParseCore(input) : null;
return result is not null;
}C#
static void Validate(string name)
{
// Could not mark local functions with [DoesNotReturn]
// so they had to be promoted to regular private methods
if (name is null)
ThrowHelperError(nameof(name));
}
[DoesNotReturn]
private static void ThrowHelperError(string paramName)
{
throw new ArgumentNullException(paramName);
}