Since IEnumerable<string>
is a reference type, the only possible default parameter is null
. There's absolutely nothing else you can stick there. But! You can reference the property from the primary constructor in the initialization of an explicitly declared "long-form" auto-property. This would allow you to coalesce the value as it's assigned to the property.
public record MyRecord(IEnumerable<string>? Strings = null)
{
public IEnumerable<string> Strings { get; init; } = Strings ?? Enumerable.Empty<string>();
}
See SharpLab
This actually generates a constructor for your record similar to the one you had originally. Here's what the above link generates (with the nullable attributes converted back to ?
) for the constructor:
public MyRecord(IEnumerable<string>? Strings = null)
{
<Strings>k__BackingField = Strings ?? Enumerable.Empty<string>();
base..ctor();
}
It's a little more verbose/not as compact as the one-liner but it's the only way to accomplish what you ask for with a record
and it's still shorter than the non-record
version.
Also note that if you look at the generated code, the property ends up being declared non-nullable, while the constructor parameter is nullable. Compare this to the single line version you started with, where the generated parameter would be nullable to match the primary constructor declaration. In this solution, you could change this behavior (if you needed to) and explicitly mark the long-form property nullable as well.