Table of Contents

Money Struct

Definition

Namespace
Bodu.Financial
Assembly
Bodu.Financial.dll
Package
Bodu.Financial 1.0.0
Source
Money.Allocation.cs

Represents an immutable monetary amount whose currency is identified at runtime by ISO 4217 code, in contrast to Money<TCurrency> where the currency is a type parameter.

public readonly struct Money : ISpanFormattable, IFormattable, IUtf8SpanFormattable, IEquatable<Money>, IComparable<Money>, IComparable, ISpanParsable<Money>, IParsable<Money>
Implements
Inherited Members
Extension Methods

Remarks

Money is the runtime-tagged counterpart of Money<TCurrency>. Use it when the currency is data rather than part of the type - for example, when deserialising payloads that carry the currency code, or when modelling a generic invoicing engine that processes arbitrary currencies. The trade-off is that cross-currency arithmetic and comparison surface as InvalidOperationException at runtime instead of as compile errors.

The amount is rounded on construction to the minor-unit precision reported by CurrencyRegistry for the supplied ISO code, using banker's rounding by default. A structurally valid ISO code that is not a known currency is rejected.

JSON serialization ships in the companion Bodu.Financial.Serialization.Json package; the type carries no [JsonConverter] attribute, so register the financial converters on the target JsonSerializerOptions via its AddFinancialJsonConverters extension.

// Construct from an amount + ISO code; the amount is rounded to the currency's minor units on creation.
var price = new Money(19.999m, CurrencyCode.USD);   // 20.00 USD (banker's rounding)
var tax = new Money(1.60m, CurrencyCode.USD);

// Same-currency arithmetic and comparison.
Money total = price + tax;                          // 21.60 USD
bool isDearer = total > price;                      // true

// Scaling by a scalar re-rounds the product to the minor unit.
Money tripled = price * 3m;                         // 60.00 USD

// Mixing currencies throws at runtime - use Money<TCurrency> for compile-time safety.
var euros = new Money(5m, CurrencyCode.EUR);
// _ = total + euros;                               // throws InvalidOperationException

Constructors

Money(decimal, CurrencyCode, MidpointRounding)

Initializes a new instance of the Money struct from an amount and currency, rounding the amount to the currency's minor-unit precision using the supplied rule.

public Money(decimal amount, CurrencyCode code, MidpointRounding rounding = MidpointRounding.ToEven)

Parameters

amount decimal

The monetary amount in the major unit.

code CurrencyCode

The currency identifying this value.

rounding MidpointRounding

The midpoint-rounding rule applied when normalising to the minor-unit precision.

Exceptions

ArgumentOutOfRangeException

code is None or is not a defined CurrencyCode member.

Properties

Amount

Gets the rounded monetary amount in the major unit of the currency.

public decimal Amount { get; }

Property Value

decimal

The amount stored by this instance.

Code

Gets the currency identifying this value.

public CurrencyCode Code { get; }

Property Value

CurrencyCode

The stored CurrencyCode, or None for a default-initialised value.

HasCurrency

Gets a value indicating whether this value carries a currency and can participate in financial operations.

public bool HasCurrency { get; }

Property Value

bool

true when this value carries an ISO code; otherwise false for a default-initialised value.

IsDefault

Gets a value indicating whether this value is a default-initialised, currency-less Money.

public bool IsDefault { get; }

Property Value

bool

true when this value was produced by default(Money) and therefore carries no currency; otherwise false.

Remarks

A default-initialised Money is the unavoidable zero value of the struct, not a valid financial zero. It carries no currency and is rejected by every arithmetic, allocation, and conversion operation; use Zero(CurrencyCode) to obtain a usable zero for a specific currency. Equality, hashing, and formatting remain safe to call so diagnostic surfaces do not throw.

MinorUnits

Gets the minor-unit precision of this value.

public int MinorUnits { get; }

Property Value

int

The explicit scale supplied at construction when this value carries one; otherwise the currency's minor-unit precision as reported by CurrencyRegistry, or zero when the currency is unknown to the registry.

Remarks

A value materialised by the settlement path (RoundToMoney(MonetaryContext?)) at a precision other than the currency's registered minor units reports that explicit scale, keeping the stored precision and the reported minor units self-consistent. Ordinary construction always resolves the precision from the registry.

Methods

Allocate(int)

Distributes this amount as evenly as possible across parts shares, summing exactly to the original.

public Money[] Allocate(int parts)

Parameters

parts int

The number of shares to allocate.

Returns

Money[]

The per-share allocation.

Exceptions

InvalidOperationException

This value is a default-initialised, currency-less Money.

ArgumentOutOfRangeException

parts is less than or equal to zero.

Allocate(ReadOnlySpan<decimal>)

Distributes this amount across the supplied non-negative ratios in proportion to their magnitudes.

public Money[] Allocate(ReadOnlySpan<decimal> ratios)

Parameters

ratios ReadOnlySpan<decimal>

The non-negative weights.

Returns

Money[]

The per-ratio allocation, whose sum equals this instance. Residual minor units are distributed by the largest-remainder method - each slot receives one extra unit in descending order of its fractional remainder, with ties broken by stable input order. Zero-ratio slots never receive residual.

Exceptions

InvalidOperationException

This value is a default-initialised, currency-less Money.

ArgumentException

The ratios are empty, contain a negative value, or sum to zero.

As<TCurrency>()

Converts this Money to a strongly-typed Money<TCurrency> when the runtime currency matches TCurrency.

public Money<TCurrency> As<TCurrency>() where TCurrency : ICurrency

Returns

Money<TCurrency>

The strongly-typed monetary value.

Type Parameters

TCurrency

The target currency type.

Exceptions

InvalidOperationException

The instance's Code does not match the currency of TCurrency.

CompareTo(Money)

Compares this instance to another value of the same currency.

public int CompareTo(Money other)

Parameters

other Money

The value to compare against.

Returns

int

A negative, zero, or positive value.

Exceptions

InvalidOperationException

The operands have different currencies.

CompareTo(object?)

Compares this instance to a boxed value.

public int CompareTo(object? obj)

Parameters

obj object

The boxed value.

Returns

int

A negative, zero, or positive value.

Exceptions

ArgumentException

obj is not a Money.

Convert(ExchangeRate, MonetaryContext?)

Converts this amount using an auditable ExchangeRate quote, rounding to the target currency under context.

public Money Convert(ExchangeRate rate, MonetaryContext? context = null)

Parameters

rate ExchangeRate

The exchange-rate quote whose source currency must match this value's currency.

context MonetaryContext

The monetary context governing rounding; null selects Default.

Returns

Money

The converted Money in the rate's target currency.

Remarks

Prefer this quote-first overload over the raw-decimal Convert(string, decimal, MidpointRounding) surface: it preserves the rate's direction, date, provider, and inversion metadata for downstream audit, and the companion ConvertWithResult(ExchangeRate, MonetaryContext?) returns that metadata alongside the rounding adjustment.

Exceptions

InvalidOperationException

The rate's source currency does not match this value's Code.

Convert(string, decimal)

Converts this amount to a different currency at the supplied exchange rate, rounding to the target currency's minor-unit precision.

public Money Convert(string targetIsoCode, decimal exchangeRate)

Parameters

targetIsoCode string

The ISO 4217 code of the destination currency.

exchangeRate decimal

The rate, expressed as units of the destination per unit of the source.

Returns

Money

The converted Money.

Exceptions

ArgumentNullException

targetIsoCode is null.

ArgumentException

targetIsoCode is empty or whitespace.

ArgumentOutOfRangeException

exchangeRate is negative.

Convert(string, decimal, MidpointRounding)

Converts this amount to a different currency at the supplied exchange rate, using the specified rounding rule.

public Money Convert(string targetIsoCode, decimal exchangeRate, MidpointRounding rounding)

Parameters

targetIsoCode string

The ISO 4217 code of the destination currency.

exchangeRate decimal

The rate, expressed as units of the destination per unit of the source.

rounding MidpointRounding

The midpoint-rounding rule applied at the target precision.

Returns

Money

The converted Money.

Exceptions

ArgumentNullException

targetIsoCode is null.

ArgumentException

targetIsoCode is empty or whitespace.

ArgumentOutOfRangeException

exchangeRate is negative.

ConvertWithResult(ExchangeRate, MonetaryContext?)

Converts this amount using an auditable ExchangeRate quote and returns the full conversion result, including the rate, context, and rounding adjustment.

public MoneyConversionResult ConvertWithResult(ExchangeRate rate, MonetaryContext? context = null)

Parameters

rate ExchangeRate

The exchange-rate quote whose source currency must match this value's currency.

context MonetaryContext

The monetary context governing rounding; null selects Default.

Returns

MoneyConversionResult

The MoneyConversionResult describing the conversion.

Exceptions

InvalidOperationException

The rate's source currency does not match this value's Code.

Convert<TTarget>(decimal)

Converts this amount to a strongly-typed Money<TCurrency> at the supplied exchange rate.

public Money<TTarget> Convert<TTarget>(decimal exchangeRate) where TTarget : ICurrency

Parameters

exchangeRate decimal

The rate, expressed as units of the destination per unit of the source.

Returns

Money<TTarget>

The converted typed monetary value.

Type Parameters

TTarget

The destination currency type.

Exceptions

ArgumentOutOfRangeException

exchangeRate is negative.

Convert<TTarget>(decimal, MidpointRounding)

Converts this amount to a strongly-typed Money<TCurrency> at the supplied exchange rate, using the specified rounding rule.

public Money<TTarget> Convert<TTarget>(decimal exchangeRate, MidpointRounding rounding) where TTarget : ICurrency

Parameters

exchangeRate decimal

The rate, expressed as units of the destination per unit of the source.

rounding MidpointRounding

The midpoint-rounding rule.

Returns

Money<TTarget>

The converted typed monetary value.

Type Parameters

TTarget

The destination currency type.

Exceptions

ArgumentOutOfRangeException

exchangeRate is negative.

Divide(decimal)

Divides this amount by divisor using banker's rounding, identical to the / operator.

public Money Divide(decimal divisor)

Parameters

divisor decimal

The scalar divisor.

Returns

Money

The quotient, rounded to the currency's minor units using banker's rounding.

Exceptions

InvalidOperationException

This value is a default-initialised, currency-less Money.

DivideByZeroException

divisor is zero.

Divide(decimal, MidpointRounding)

Divides this amount by divisor and rounds the result to the currency's minor-unit precision using the supplied rule.

public Money Divide(decimal divisor, MidpointRounding rounding)

Parameters

divisor decimal

The scalar divisor.

rounding MidpointRounding

The midpoint-rounding rule applied to the quotient.

Returns

Money

The quotient, rounded to the currency's minor units using rounding.

Remarks

Use this overload when a non-default rounding rule must be applied. The / operator forces banker's rounding because operator signatures cannot accept a rounding-mode parameter.

Exceptions

InvalidOperationException

This value is a default-initialised, currency-less Money.

DivideByZeroException

divisor is zero.

Equals(Money)

Determines whether two instances are equal in both currency and amount.

public bool Equals(Money other)

Parameters

other Money

The other value.

Returns

bool

true when both currency and amount match; otherwise false.

Remarks

Equality is numeric and follows decimal semantics: the reported minor-unit scale is not part of the identity, so a settled 12.50 USD equals a six-place unit price of 12.500000 USD even though the two values format and serialize differently. (This is the decimal convention rather than Java's scale-sensitive BigDecimal.equals.) Compare MinorUnits explicitly when the precision itself is significant.

Equals(object?)

Determines whether this instance equals the boxed obj.

public override bool Equals(object? obj)

Parameters

obj object

The object to compare.

Returns

bool

true when obj is a matching Money.

From(decimal, CurrencyCode, MidpointRounding)

Creates a runtime-tagged Money from the supplied amount and ISO 4217 enum value.

public static Money From(decimal amount, CurrencyCode code, MidpointRounding rounding = MidpointRounding.ToEven)

Parameters

amount decimal

The monetary amount in the major unit.

code CurrencyCode

The ISO 4217 currency code.

rounding MidpointRounding

The midpoint-rounding rule applied when normalising to the minor-unit precision.

Returns

Money

The constructed monetary value.

Exceptions

ArgumentOutOfRangeException

code is None or is not a defined CurrencyCode member.

From(decimal, CurrencyInfo, MidpointRounding)

Creates a runtime-tagged Money from the supplied amount and currency metadata.

public static Money From(decimal amount, CurrencyInfo currency, MidpointRounding rounding = MidpointRounding.ToEven)

Parameters

amount decimal

The monetary amount in the major unit.

currency CurrencyInfo

The currency metadata identifying the result's currency.

rounding MidpointRounding

The midpoint-rounding rule applied when normalising to the minor-unit precision.

Returns

Money

The constructed monetary value.

Exceptions

ArgumentNullException

currency is null.

InvalidOperationException

currency's ISO code does not correspond to any CurrencyCode member.

FromExplicitScale(decimal, CurrencyCode, int, MidpointRounding)

Creates a Money that carries an explicit minor-unit scale, rounding the amount to that scale and reporting it from MinorUnits.

public static Money FromExplicitScale(decimal amount, CurrencyCode code, int minorUnits, MidpointRounding rounding = MidpointRounding.ToEven)

Parameters

amount decimal

The monetary amount in the major unit.

code CurrencyCode

The currency identifying this value.

minorUnits int

The number of fractional digits to round to and report as the value's minor units.

rounding MidpointRounding

The midpoint-rounding rule applied when normalising to minorUnits.

Returns

Money

The constructed monetary value carrying an explicit scale.

Examples

using Bodu.Financial;

// A share price quoted to six decimal places in two-decimal USD.
Money price = Money.FromExplicitScale(145.678912m, CurrencyCode.USD, 6);

price.MinorUnits;      // 6
price.ToString("R");   // "USD 145.678912"

Remarks

This is the direct construction route for values whose precision is known up front and differs from the currency's registered minor units - typically unit prices such as a six-decimal-place share price in a two-decimal currency. The supplied scale is stored with the value: MinorUnits reports it, formatting pads to it, arithmetic and allocation round intermediate results to it rather than to the registry precision, and the JSON converters persist it so a round-trip restores the same precision.

For amounts that are computed rather than quoted, prefer accumulating in CalculatedMoney and settling once through RoundToMoney(MonetaryContext?) with Custom - that path defers rounding to a single, explicit settlement decision and produces the same explicit-scale value.

Exceptions

ArgumentOutOfRangeException

code is not a defined currency, or minorUnits is outside the range 0 to 28.

GetHashCode()

Returns a hash code combining the currency and amount.

public override int GetHashCode()

Returns

int

A 32-bit hash code.

Multiply(decimal)

Multiplies this amount by multiplier using banker's rounding, identical to the * operator.

public Money Multiply(decimal multiplier)

Parameters

multiplier decimal

The scalar multiplier.

Returns

Money

The product, rounded to the currency's minor units using banker's rounding.

Exceptions

InvalidOperationException

This value is a default-initialised, currency-less Money.

Multiply(decimal, MidpointRounding)

Multiplies this amount by multiplier and rounds the result to the currency's minor-unit precision using the supplied rule.

public Money Multiply(decimal multiplier, MidpointRounding rounding)

Parameters

multiplier decimal

The scalar multiplier.

rounding MidpointRounding

The midpoint-rounding rule applied to the product.

Returns

Money

The product, rounded to the currency's minor units using rounding.

Remarks

Use this overload when a non-default rounding rule (for example, AwayFromZero for retail-tax workflows) must be applied. The * operator forces banker's rounding because operator signatures cannot accept a rounding-mode parameter.

Exceptions

InvalidOperationException

This value is a default-initialised, currency-less Money.

Of<TCurrency>(decimal)

Creates a Money<TCurrency> from the supplied amount, rounding to the currency's minor-unit precision using banker's rounding.

public static Money<TCurrency> Of<TCurrency>(decimal amount) where TCurrency : ICurrency

Parameters

amount decimal

The monetary amount in the major unit of TCurrency.

Returns

Money<TCurrency>

The constructed monetary value.

Type Parameters

TCurrency

The currency type identifier.

Of<TCurrency>(decimal, MidpointRounding)

Creates a Money<TCurrency> from the supplied amount and rounding rule.

public static Money<TCurrency> Of<TCurrency>(decimal amount, MidpointRounding rounding) where TCurrency : ICurrency

Parameters

amount decimal

The monetary amount.

rounding MidpointRounding

The midpoint-rounding rule applied when normalizing to the minor-unit precision.

Returns

Money<TCurrency>

The constructed monetary value.

Type Parameters

TCurrency

The currency type identifier.

Parse(string, MoneyParseOptions)

Parses a Money using the supplied options.

public static Money Parse(string s, MoneyParseOptions options)

Parameters

s string

The text to parse.

options MoneyParseOptions

The parse options controlling mode and culture.

Returns

Money

The parsed value.

Exceptions

ArgumentNullException

s or options is null.

FormatException

The input is not valid under options.

Rescale(int, MidpointRounding)

Returns this value re-expressed at the supplied minor-unit scale, rounding the amount when the new scale is coarser and padding the reported precision when it is finer.

public Money Rescale(int minorUnits, MidpointRounding rounding = MidpointRounding.ToEven)

Parameters

minorUnits int

The number of fractional digits the result reports as its minor units.

rounding MidpointRounding

The midpoint-rounding rule applied when normalising to minorUnits.

Returns

Money

The re-scaled monetary value.

Examples

using Bodu.Financial;

Money price = Money.FromExplicitScale(145.678912m, CurrencyCode.USD, 6);

price.Rescale(2);   // USD 145.68  (MinorUnits = 2)
price.Rescale(8);   // USD 145.67891200 (MinorUnits = 8, amount unchanged)

Remarks

Rescaling to a coarser precision drops sub-scale digits under rounding - rescaling a six-place unit price to a currency's two registered minor units is a plain settlement of that single value. Rescaling finer is lossless: the amount is unchanged and only the reported precision (and therefore formatting and the serialized scale) widens. The equivalent operation is transformScale in dinero.js and withScale on Joda's BigMoney.

For policy-aware settlement - cash-rounding increments, a ScalePolicy, or a configured rounding strategy - settle through RoundToMoney(MonetaryContext?) instead; this method applies only the supplied midpoint rule.

Exceptions

InvalidOperationException

This value is a default-initialised, currency-less Money.

ArgumentOutOfRangeException

minorUnits is outside the range 0 to 28.

ToCalculated()

Returns a high-precision CalculatedMoney in the same currency, suitable for deferred-rounding calculation chains.

public CalculatedMoney ToCalculated()

Returns

CalculatedMoney

A CalculatedMoney carrying this value's amount and currency.

Exceptions

InvalidOperationException

This value carries no currency (default-initialised).

ToString()

Returns the default string representation: ISO code followed by the amount at the currency's minor-unit precision under the current culture.

public override string ToString()

Returns

string

The formatted string.

ToString(string?)

Returns a string representation using the supplied format specifier.

public string ToString(string? format)

Parameters

format string

The format specifier.

Returns

string

The formatted string.

ToString(string?, IFormatProvider?)

Returns a string representation using the supplied format specifier and culture.

public string ToString(string? format, IFormatProvider? formatProvider)

Parameters

format string

The format specifier.

formatProvider IFormatProvider

The culture used to render the numeric component.

Returns

string

The formatted string.

TrimScale()

Returns this value with trailing-zero precision removed: the reported scale is reduced to the smallest scale that still represents the amount exactly, but never below the currency's registered minor units.

public Money TrimScale()

Returns

Money

The trimmed monetary value, or this value unchanged when no trailing-zero scale can be removed.

Remarks

Trimming never changes the numeric amount - only the reported precision. A six-place 12.500000 USD trims to the registered two places (12.50), a six-place 12.340010 trims to five, and a value whose finest digits are significant (12.345678) is returned unchanged. The registered minor units are the floor, so ordinary money is always a no-op. The equivalent operation is trimScale in dinero.js.

Exceptions

InvalidOperationException

This value is a default-initialised, currency-less Money.

TryAs<TCurrency>(out Money<TCurrency>)

Attempts to convert this Money to a strongly-typed Money<TCurrency>.

public bool TryAs<TCurrency>(out Money<TCurrency> result) where TCurrency : ICurrency

Parameters

result Money<TCurrency>

When this method returns true, the strongly-typed value.

Returns

bool

true when the currencies match; otherwise false.

Type Parameters

TCurrency

The target currency type.

TryFormat(Span<byte>, out int, ReadOnlySpan<char>, IFormatProvider?)

Attempts to format this value into a UTF-8 byte span.

public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider)

Parameters

utf8Destination Span<byte>

The destination UTF-8 span.

bytesWritten int

The number of bytes written.

format ReadOnlySpan<char>

The format specifier.

provider IFormatProvider

The culture provider.

Returns

bool

true if the span was large enough.

TryFormat(Span<char>, out int, ReadOnlySpan<char>, IFormatProvider?)

Attempts to format this value into a character span.

public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider)

Parameters

destination Span<char>

The destination span.

charsWritten int

The number of characters written.

format ReadOnlySpan<char>

The format specifier.

provider IFormatProvider

The culture provider.

Returns

bool

true if the span was large enough.

TryParse(ReadOnlySpan<char>, MoneyParseOptions, out Money)

Attempts to parse a Money using the supplied options.

public static bool TryParse(ReadOnlySpan<char> s, MoneyParseOptions options, out Money result)

Parameters

s ReadOnlySpan<char>

The text to parse.

options MoneyParseOptions

The parse options controlling mode and culture.

result Money

When this method returns true, the parsed value; otherwise the default.

Returns

bool

true on success.

Exceptions

ArgumentNullException

options is null.

ArgumentOutOfRangeException

options.Mode is not a defined value.

Zero(CurrencyCode)

Returns a Money representing zero of the specified currency.

public static Money Zero(CurrencyCode code)

Parameters

code CurrencyCode

The currency identifying the zero value.

Returns

Money

A zero Money in code.

Exceptions

ArgumentOutOfRangeException

code is None or is not a defined CurrencyCode member.

Zero<TCurrency>()

Returns the zero value of TCurrency.

public static Money<TCurrency> Zero<TCurrency>() where TCurrency : ICurrency

Returns

Money<TCurrency>

The zero monetary amount.

Type Parameters

TCurrency

The currency type identifier.

Operators

operator +(Money, Money)

Adds two monetary values denominated in the same currency.

public static Money operator +(Money left, Money right)

Parameters

left Money

The first amount.

right Money

The second amount.

Returns

Money

The sum of left and right.

Remarks

When the operands report different minor-unit scales - for example a two-decimal settled amount and a six-decimal unit price - the result carries the finer (maximum) of the two scales, mirroring decimal addition semantics. The sum is exact at that scale, so no rounding occurs and the reported precision is the same regardless of operand order.

Exceptions

InvalidOperationException

The operands have different ISO codes.

OverflowException

The sum falls outside the range of decimal.

operator /(Money, Money)

Returns the dimensionless ratio of two monetary values in the same currency.

public static decimal operator /(Money left, Money right)

Parameters

left Money

The dividend.

right Money

The divisor.

Returns

decimal

The ratio.

Exceptions

InvalidOperationException

The operands have different ISO codes.

DivideByZeroException

right has an amount of zero.

operator /(Money, decimal)

Divides a monetary value by a scalar, rounding the quotient to the currency's minor-unit precision using banker's rounding (ToEven).

public static Money operator /(Money left, decimal right)

Parameters

left Money

The amount.

right decimal

The scalar divisor.

Returns

Money

The quotient, rounded to the currency's minor units using banker's rounding.

Remarks

Use Divide(decimal, MidpointRounding) when a rounding rule other than banker's rounding is required; the operator cannot accept a rounding-mode parameter.

Exceptions

InvalidOperationException

left is a default-initialised, currency-less Money.

DivideByZeroException

right is zero.

operator ==(Money, Money)

Determines whether two values are equal.

public static bool operator ==(Money left, Money right)

Parameters

left Money

The first value.

right Money

The second value.

Returns

bool

true when equal; otherwise false.

operator >(Money, Money)

Compares two amounts in the same currency.

public static bool operator >(Money left, Money right)

Parameters

left Money

The first amount.

right Money

The second amount.

Returns

bool

true when left is greater than right; otherwise false.

Exceptions

InvalidOperationException

The operands have different ISO codes.

operator >=(Money, Money)

Compares two amounts in the same currency.

public static bool operator >=(Money left, Money right)

Parameters

left Money

The first amount.

right Money

The second amount.

Returns

bool

true when left is greater than or equal to right; otherwise false.

Exceptions

InvalidOperationException

The operands have different ISO codes.

operator !=(Money, Money)

Determines whether two values differ.

public static bool operator !=(Money left, Money right)

Parameters

left Money

The first value.

right Money

The second value.

Returns

bool

true when they differ; otherwise false.

operator <(Money, Money)

Compares two amounts in the same currency.

public static bool operator <(Money left, Money right)

Parameters

left Money

The first amount.

right Money

The second amount.

Returns

bool

true when left is less than right; otherwise false.

Exceptions

InvalidOperationException

The operands have different ISO codes.

operator <=(Money, Money)

Compares two amounts in the same currency.

public static bool operator <=(Money left, Money right)

Parameters

left Money

The first amount.

right Money

The second amount.

Returns

bool

true when left is less than or equal to right; otherwise false.

Exceptions

InvalidOperationException

The operands have different ISO codes.

operator *(Money, decimal)

Multiplies a monetary value by a scalar, rounding the product to the currency's minor-unit precision using banker's rounding (ToEven).

public static Money operator *(Money left, decimal right)

Parameters

left Money

The amount.

right decimal

The scalar.

Returns

Money

The product, rounded to the currency's minor units using banker's rounding.

Remarks

Use Multiply(decimal, MidpointRounding) when a rounding rule other than banker's rounding is required; the operator cannot accept a rounding-mode parameter.

Exceptions

InvalidOperationException

left is a default-initialised, currency-less Money.

operator *(decimal, Money)

Multiplies a scalar by a monetary value, rounding the product to the currency's minor-unit precision using banker's rounding (ToEven).

public static Money operator *(decimal left, Money right)

Parameters

left decimal

The scalar.

right Money

The amount.

Returns

Money

The product, rounded to the currency's minor units using banker's rounding.

Remarks

Use Multiply(decimal, MidpointRounding) when a rounding rule other than banker's rounding is required; the operator cannot accept a rounding-mode parameter.

Exceptions

InvalidOperationException

right is a default-initialised, currency-less Money.

operator -(Money, Money)

Subtracts one monetary value from another.

public static Money operator -(Money left, Money right)

Parameters

left Money

The minuend.

right Money

The subtrahend.

Returns

Money

The difference.

Remarks

When the operands report different minor-unit scales, the result carries the finer (maximum) of the two scales, mirroring decimal subtraction semantics; the difference is exact at that scale and the reported precision does not depend on operand order.

Exceptions

InvalidOperationException

The operands have different ISO codes.

OverflowException

The difference falls outside the range of decimal.

operator -(Money)

Negates a monetary value.

public static Money operator -(Money value)

Parameters

value Money

The amount to negate.

Returns

Money

A Money with the same ISO code and negated amount.

Exceptions

InvalidOperationException

value is a default-initialised, currency-less Money.

operator +(Money)

Returns the operand unchanged.

public static Money operator +(Money value)

Parameters

value Money

The amount.

Returns

Money

The unchanged value.

Explicit Interface Implementations

Parse(ReadOnlySpan<char>, IFormatProvider?)

Parses a Money from a span representation.

static Money Parse(ReadOnlySpan<char> s, IFormatProvider? provider)

Parameters

s ReadOnlySpan<char>

The text to parse.

provider IFormatProvider

The culture used to interpret the numeric component.

Returns

Money

The parsed value.

Exceptions

FormatException

The input is not a valid representation.

Parse(string, IFormatProvider?)

Parses a Money from "<ISO> <amount>" or "<amount> <ISO>".

static Money Parse(string s, IFormatProvider? provider)

Parameters

s string

The text to parse.

provider IFormatProvider

The culture used to interpret the numeric component.

Returns

Money

The parsed value.

Examples

using System.Globalization;
using Bodu.Financial;

// The ISO code may lead or trail the amount; it selects the runtime currency.
var a = Money.Parse("USD 19.99", CultureInfo.InvariantCulture);
var b = Money.Parse("19.99 USD", CultureInfo.InvariantCulture);   // equal to a

// A bare amount has no currency and fails to parse.
bool ok = Money.TryParse("19.99", CultureInfo.InvariantCulture, out _);   // false

Remarks

Text carrying more fractional digits than the currency's registered minor units - a unit price such as "USD 12.345678" - parses to a value reporting that finer scale from MinorUnits, making this method the inverse of the round-trip ("R") format. Text at or below the registered precision parses at the registry precision, unchanged from earlier behaviour.

Exceptions

ArgumentNullException

s is null.

FormatException

The input is not a valid Money representation.

TryParse(ReadOnlySpan<char>, IFormatProvider?, out Money)

Attempts to parse a Money from a span.

static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out Money result)

Parameters

s ReadOnlySpan<char>

The text to parse.

provider IFormatProvider

The culture provider.

result Money

The parsed value or default.

Returns

bool

true on success.

TryParse(string?, IFormatProvider?, out Money)

Attempts to parse a Money from a string.

static bool TryParse(string? s, IFormatProvider? provider, out Money result)

Parameters

s string

The text to parse.

provider IFormatProvider

The culture provider.

result Money

When this method returns true, the parsed value; otherwise the default.

Returns

bool

true on success.

Applies to

ProductVersions
.NET8, 10