NDLRGEN048: Constructor guard incompatible with member type¶
Cause¶
A built-in [ConstructorGuard] kind is applied to a participating field or record
property whose type it cannot validate:
NotNullOrEmptyorNotNullOrWhiteSpaceapplied to a member that is notstring.NotNullapplied to a member where a runtimenullvalue is never possible: a non-nullable value type (other thanNullable<T>).
Rule Description¶
NotNullOrEmpty and NotNullOrWhiteSpace call System.ArgumentException.ThrowIfNullOrEmpty / ThrowIfNullOrWhiteSpace, both of which only accept a string. Applying either to a non-string member would not compile as generated source, so it is rejected earlier, at the attribute usage site, with a clear message.
NotNull is meaningful for any reference type (nullable or not), for Nullable<T> value types, and for a type parameter that is not constrained to a value type. It is rejected on a plain non-nullable value type (such as int or Guid) or a struct/unmanaged-constrained type parameter because a runtime null is never possible for that type -- the guard could never fail, so it only adds dead code.
How to Fix¶
Choose a guard kind compatible with the member's type, or change the member's type:
using NexusLabs.Needlr.Generators;
[GenerateConstructor]
public partial class UserService
{
// WRONG - NDLRGEN048: NotNullOrWhiteSpace only applies to string fields
[ConstructorGuard(ConstructorGuardKind.NotNullOrWhiteSpace)]
private readonly int _retryCount;
// WRONG - NDLRGEN048: a non-nullable int can never be null
[ConstructorGuard(ConstructorGuardKind.NotNull)]
private readonly int _timeoutSeconds;
}
// CORRECT - NotNullOrWhiteSpace on a string field
[GenerateConstructor]
public partial class UserService
{
[ConstructorGuard(ConstructorGuardKind.NotNullOrWhiteSpace)]
private readonly string _tenantName;
// CORRECT - NotNull on a Nullable<T> value type, where null is possible
[ConstructorGuard(ConstructorGuardKind.NotNull)]
private readonly int? _optionalTimeoutSeconds;
}
// CORRECT - an unconstrained type parameter may be a reference type
public partial class ValueHolder<T>
{
[ConstructorGuard(ConstructorGuardKind.NotNull)]
private readonly T _value;
}
See Also¶
- NDLRGEN047 - Invalid constructor guard enum value
- NDLRGEN051 - Custom constructor guard method is invalid
- Generated Constructors
- Generated Record Constructor Overloads