diff --git a/NeosModLoader/ModConfiguration.cs b/NeosModLoader/ModConfiguration.cs index 14b5f82..893d8e1 100644 --- a/NeosModLoader/ModConfiguration.cs +++ b/NeosModLoader/ModConfiguration.cs @@ -363,8 +363,7 @@ public void Set(ModConfigurationKey key, object? value, string? eventLabel = nul if (value == null) { - bool cannotBeNull = definingKey!.ValueType().IsValueType && Nullable.GetUnderlyingType(definingKey!.ValueType()) == null; - if (cannotBeNull) + if (Util.CannotBeNull(definingKey!.ValueType())) { throw new ArgumentException($"null cannot be assigned to {definingKey.ValueType()}"); } diff --git a/NeosModLoader/ModConfigurationKey.cs b/NeosModLoader/ModConfigurationKey.cs index b5725a4..f29c983 100644 --- a/NeosModLoader/ModConfigurationKey.cs +++ b/NeosModLoader/ModConfigurationKey.cs @@ -136,13 +136,27 @@ public ModConfigurationKey(string name, string? description = null, Func? com /// true if the value is valid public override bool Validate(object? value) { - // specifically allow nulls for class types - if (value is T || (value is null && !typeof(T).IsValueType)) + if (value is T typedValue) { - return ValidateTyped((T?)value); + // value is of the correct type + return ValidateTyped(typedValue); + } + else if (value == null) + { + if (Util.CanBeNull(ValueType())) + { + // null is valid for T + return ValidateTyped((T?)value); + } + else + { + // null is not valid for T + return false; + } } else { + // value is of the wrong type return false; } } diff --git a/NeosModLoader/Util.cs b/NeosModLoader/Util.cs index c07d6b9..6dd0321 100644 --- a/NeosModLoader/Util.cs +++ b/NeosModLoader/Util.cs @@ -90,5 +90,17 @@ internal static HashSet ToHashSet(this IEnumerable source, IEqualityCom return new HashSet(source, comparer); } + // check if a type cannot possibly have null assigned + internal static bool CannotBeNull(Type t) + { + return t.IsValueType && Nullable.GetUnderlyingType(t) == null; + } + + // check if a type is allowed to have null assigned + internal static bool CanBeNull(Type t) + { + return !CannotBeNull(t); + } + } }