iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
C# generic math lets one generic method perform arithmetic across supported numeric types instead of requiring a separate overload for each type. Use a constraint such as where T : INumber<T> when the method needs the operations that interface provides. The feature combines C# 11 static interface members with numeric interfaces introduced in .NET 7, so check both your language version and target framework before adopting it.
What generic math solves
Without generic math, a method that adds two values of different numeric types may need a separate overload for each type. Generic math lets an algorithm express its requirements as a type constraint, then use the relevant operators on the constrained type parameter.
The .NET numeric interfaces became part of the base class library in .NET 7. C# 11 added the static abstract and static virtual interface member support that makes operators and other static members available to generic code through constraints. Microsoft’s overview describes how this can reduce redundant overloads in libraries and indirectly give their users APIs that support more types.
Microsoft Learn says 20 numeric types provided by the .NET base class library implement the generic interfaces; that count appears on its page last updated August 3, 2022, and should not be read as a count of all possible custom numeric types. See Microsoft’s overview of generic interfaces in .NET.
#1 Best Overall
How to write a generic numeric method
Add two values with INumber
For a method that needs ordinary numeric addition, write:
using System.Numerics;
static T Add<T>(T left, T right)
where T : INumber<T>
=> left + right;
The constraint tells the compiler that T implements the operations exposed by INumber<T>, including addition. The compiler can therefore check left + right even though the concrete type is not known until the method is called. For example, supported types such as int or double can use the same method.
Rank #2
INumber<TSelf> inherits multiple smaller interfaces, including IAdditionOperators<TSelf, TOther, TResult>. It is a convenient broad constraint, not a requirement for every generic numeric algorithm. The .NET 7 API reference lists INumber’s inherited interfaces.
Why the operator works
In C# 11 and later, an interface can declare static abstract or static virtual members, including operators. A type that implements the interface supplies the corresponding static behavior. Generic code can invoke that behavior through a type parameter constrained by the interface; the operator is not being called on an object instance.
This is what makes left + right legal in the generic method: the constraint establishes that the type parameter has an appropriate addition operator. Microsoft’s static virtual interface members tutorial walks through the mechanism.
Choose the constraint that matches the algorithm
Constrain a type parameter to the capabilities the algorithm actually needs. A broad constraint is convenient when the method genuinely needs broad numeric behavior; a narrower interface states a more precise contract and may allow appropriate custom numeric types that do not implement the broader interface.
Rank #4
| Constraint or family | Use it when | Important distinction |
|---|---|---|
INumber<TSelf> |
The algorithm needs a broad set of common operations for comparable, real-like numbers. | It composes multiple interfaces, including arithmetic and comparison-related capabilities. |
INumberBase<TSelf> |
The algorithm needs a more general number concept, including concepts used by complex or imaginary numbers. | It is broader than the comparable real-like domain represented by INumber<TSelf>. |
IBinaryInteger<TSelf> |
The algorithm specifically requires binary-integer behavior. | It communicates an integer-specific requirement rather than accepting every number type. |
Floating-point interfaces, including IFloatingPointIeee754<TSelf> |
The algorithm uses operations or guarantees specific to floating-point values. | Not every numeric type implements these interfaces; for example, Int32 does not implement IFloatingPointIeee754<TSelf>. |
| Fine-grained operator, parsing, identity, or formatting interfaces | The method needs only a specific capability, such as addition, parsing, or an additive identity. | Using a smaller interface can describe the method’s actual requirements more accurately than a broad numeric constraint. |
For example, a method that only adds values may be expressible with an addition-operator interface rather than the full INumber<T> contract. A method that calls a floating-point-only operation such as floor needs a floating-point constraint; INumber<T> alone does not promise that operation. Microsoft’s generic math overview describes the numeric interface taxonomy and examples.
Free tools Windows power users keep installed
One-click scans. No signup required.
Understand the midpoint example’s overflow risk
A simple generic midpoint calculation can add the two inputs and divide by two, creating the divisor with T.CreateChecked(2):
Best Value
using System.Numerics;
static T Midpoint<T>(T left, T right)
where T : INumber<T>
=> (left + right) / T.CreateChecked(2);
CreateChecked converts the source value to the target type and throws OverflowException if that value is outside the target type’s representable range. In this example, however, conversion is not the only possible source of overflow: left + right can overflow before division. The formula is illustrative, not universally safe for every numeric type or input. If the inputs can approach the type’s limits, choose an alternative midpoint algorithm suited to the type and its arithmetic semantics. Microsoft’s tutorial flags the addition-overflow caveat.
Check language and framework compatibility
- Language version: The static interface member feature used by generic math requires C# 11 or later.
- Target framework: The numeric interface family is documented as introduced in .NET 7. Confirm that the project targets a framework providing the interfaces you use.
- Concrete types: The built-in numeric types were updated to implement the interfaces in .NET 7. A custom numeric type must implement the relevant interface members before it can satisfy the constraint.
- Constraint choice: Confirm that every operation in the method is promised by the chosen interface rather than relying on a capability of one particular type.
Language version and target framework are separate compatibility questions: selecting a newer compiler language version does not by itself add a missing framework interface. Microsoft’s generic interfaces documentation gives the .NET 7 context.
Implementing a custom generic-math type
When implementing one of these interfaces, its self type parameter must identify the implementing type. For example, a type implementing an interface shaped like INumber<TSelf> uses itself for TSelf, following the recursive generic pattern used by the interfaces.
For projects using the .NET 10 analyzer configuration, rule CA2260 warns when a generic math interface is implemented with the wrong self-recurring type argument. The rule’s documentation explains that generic constraints provide access to static abstract members and that the implementing type must be used as the self type. This is specific guidance for that analyzer rule and target context; check the analyzer documentation applicable to other project versions. Read Microsoft’s CA2260 guidance.
Quick Recap
When generic math is useful
- Use it when an algorithm should work over several numeric types and those types share the operations the algorithm needs.
- Prefer one generic implementation over repeated overloads when the behavior is genuinely the same across those types.
- Keep overloads or specialized implementations when types require different behavior, precision handling, overflow policy, or domain-specific semantics.
- Do not assume that a generic constraint makes an algorithm safe from overflow, rounding, or other type-specific behavior; it only establishes the capabilities promised by the interface.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

