diff --git a/src/Vogen/GenerateCodeForBsonSerializers.cs b/src/Vogen/GenerateCodeForBsonSerializers.cs
index 4849e76df4..f9d309e60b 100644
--- a/src/Vogen/GenerateCodeForBsonSerializers.cs
+++ b/src/Vogen/GenerateCodeForBsonSerializers.cs
@@ -18,6 +18,7 @@ internal class GenerateCodeForBsonSerializers
///
///
///
+ ///
public static void GenerateForApplicableValueObjects(SourceProductionContext context,
Compilation compilation,
List workItems,
diff --git a/src/Vogen/GenerateCodeForINumber.cs b/src/Vogen/GenerateCodeForINumber.cs
index 2f32a2b653..413757e00f 100644
--- a/src/Vogen/GenerateCodeForINumber.cs
+++ b/src/Vogen/GenerateCodeForINumber.cs
@@ -7,6 +7,7 @@
namespace Vogen;
+#if NET10_0_OR_GREATER
///
/// Generates the or
/// implementation for value objects whose underlying primitive type implements the corresponding interface.
@@ -18,6 +19,19 @@ namespace Vogen;
///
/// Requires C# 11 or later.
///
+#elif NETSTANDARD
+///
+/// Generates the System.Numerics.INumberBase of T or System.Numerics.INumberBase of T
+/// implementation for value objects whose underlying primitive type implements the corresponding interface.
+///
+/// Static abstract interface members (e.g. double.One) cannot be called on concrete
+/// types in ordinary code — they require a constrained type parameter. So the generated code
+/// includes private generic helper methods that forward every call through a type parameter,
+/// which the C# compiler can then resolve to the concrete type's implementation.
+///
+/// Requires C# 11 or later.
+///
+#endif
public static class GenerateCodeForINumber
{
private enum NumericMode { None, INumber, INumberBase }
@@ -214,7 +228,7 @@ private static void GenerateStaticProperties(StringBuilder sb, string wrapperNam
// - If an [Instance] with that name exists: the instance generates a readonly field, which does NOT
// satisfy a static abstract property. Generate an explicit interface impl that delegates to the field.
// - Otherwise: generate the normal public property.
- GenerateNumberProperty(sb, wrapperName, primitiveType, wrapperSymbol, item,
+ GenerateNumberProperty(sb, wrapperName, wrapperSymbol, item,
name: "One",
iface: $"global::System.Numerics.INumberBase<{wrapperName}>",
body: $"From(__GetOne<{primitiveType}>())");
@@ -225,17 +239,17 @@ private static void GenerateStaticProperties(StringBuilder sb, string wrapperNam
sb.AppendLine($" public static global::System.Int32 Radix => __GetRadix<{primitiveType}>();");
}
- GenerateNumberProperty(sb, wrapperName, primitiveType, wrapperSymbol, item,
+ GenerateNumberProperty(sb, wrapperName, wrapperSymbol, item,
name: "Zero",
iface: $"global::System.Numerics.INumberBase<{wrapperName}>",
body: $"From(__GetZero<{primitiveType}>())");
- GenerateNumberProperty(sb, wrapperName, primitiveType, wrapperSymbol, item,
+ GenerateNumberProperty(sb, wrapperName, wrapperSymbol, item,
name: "AdditiveIdentity",
iface: $"global::System.Numerics.IAdditiveIdentity<{wrapperName}, {wrapperName}>",
body: $"From(__GetAdditiveIdentity<{primitiveType}>())");
- GenerateNumberProperty(sb, wrapperName, primitiveType, wrapperSymbol, item,
+ GenerateNumberProperty(sb, wrapperName, wrapperSymbol, item,
name: "MultiplicativeIdentity",
iface: $"global::System.Numerics.IMultiplicativeIdentity<{wrapperName}, {wrapperName}>",
body: $"From(__GetMultiplicativeIdentity<{primitiveType}>())");
@@ -246,7 +260,6 @@ private static void GenerateStaticProperties(StringBuilder sb, string wrapperNam
private static void GenerateNumberProperty(
StringBuilder sb,
string wrapperName,
- string primitiveType,
INamedTypeSymbol wrapperSymbol,
VoWorkItem item,
string name,
diff --git a/src/Vogen/Types/ProjectName.cs b/src/Vogen/Types/ProjectName.cs
index 7235f7c183..c1d216d564 100644
--- a/src/Vogen/Types/ProjectName.cs
+++ b/src/Vogen/Types/ProjectName.cs
@@ -9,7 +9,7 @@ internal class ProjectName
/// otherwise falls back to . Either value is normalised.
///
public static ProjectName FromRootNamespaceOrAssemblyName(string? rootNamespace, string assemblyName) =>
- !string.IsNullOrWhiteSpace(rootNamespace) ? new(Normalise(rootNamespace!)) : FromAssemblyName(assemblyName);
+ !string.IsNullOrWhiteSpace(rootNamespace) ? new(Normalise(rootNamespace)) : FromAssemblyName(assemblyName);
///
/// Replaces [., ,, space, -] with [_] for use as type names etc., and ensures the result
diff --git a/tests/AnalyzerTests/DoNotUseNewAnalyzerTests.cs b/tests/AnalyzerTests/DoNotUseNewAnalyzerTests.cs
index 39cbb37b15..807fa3ac76 100644
--- a/tests/AnalyzerTests/DoNotUseNewAnalyzerTests.cs
+++ b/tests/AnalyzerTests/DoNotUseNewAnalyzerTests.cs
@@ -474,7 +474,7 @@ private async Task Run(string[] sources, IEnumerable expected)
///
/// Like but each source may optionally carry
- /// an explicit file name. A null name means auto-assign (same as the plain overload).
+ /// an explicit file name. A null name means auto-assign (same as the plain overload).
/// Named files are used to test path-sensitive filtering (e.g. .razor.g.cs vs .g.cs).
///
private async Task RunWithNamedSources(