即使在2022年,我发现自己仍然在使用类似这样的东西。我同意Michael对OP的答案,并希望将其扩展到未来的Googlers。
创建值类型在解释领域意图时具有不可替代性,并强制实现不变性。特别是在分数记录中,您将获得一个通常会导致异常的商数,但是在这里,我们可以安全地显示d / 0而无需错误,同样,所有其他继承的子级也被授予了保护(它还提供了一个极好的地方来建立简单的例程来检查有效性、数据再生(好像DBA不会犯错)、序列化问题等等)。
namespace StackOverflowing;
public record class Fraction(decimal Dividend, decimal Divisor)
{
public decimal Quotient => (Divisor > 0.0M) ? Dividend / Divisor : 0.0M;
public override string ToString()
{
return $"{Dividend} / {Divisor}";
}
};
public record class DecimalFraction(decimal Dividend, decimal Divisor) : Fraction(Dividend, Divisor)
{
public override string ToString()
{
return Quotient.ToString();
}
};
public record class Percent(decimal Value) : DecimalFraction(Value, 100.00M)
{
public override string ToString()
{
return Quotient.ToString("p");
}
};
public record class PercentagePoint(Percent Left, Percent Right)
{
public Percent Points => new(Left.Value - Right.Value);
public override string ToString()
{
return $"{Points.Dividend} points";
}
}
[TestMethod]
public void PercentScratchPad()
{
var approximatedPiFraction = new Fraction(22, 7);
var approximatedPiDecimal = new DecimalFraction(22, 7);
var percent2 = new Percent(2);
var percent212 = new Percent(212);
var points = new PercentagePoint(new Percent(50), new Percent(40));
TestContext.WriteLine($"Approximated Pi Fraction: {approximatedPiFraction}");
TestContext.WriteLine($"Approximated Pi Decimal: {approximatedPiDecimal}");
TestContext.WriteLine($"2 Percent: {percent2}");
TestContext.WriteLine($"212 Percent: {percent212}");
TestContext.WriteLine($"Percentage Points: {points}");
TestContext.WriteLine($"Percentage Points as percentage: {points.Points}");
}
PercentScratchPad
标准输出:
TestContext 消息:
Approximated Pi Fraction: 22 / 7
Approximated Pi Decimal: 3.1428571428571428571428571429
2 Percent: 2.00%
212 Percent: 212.00%
Percentage Points: 10 points
Percentage Points as percentage: 10.00%