我正在编写一个 C# 程序来计算金融资产的总价值。 每个资产都由资产 ID 表示。有专门用于计算特定资产 ID 的价值的计算器类。
public interface IAssetId
{
string GetSymbol();
}
public class Currency(string currency) : IAssetId
{
public string GetSymbol() => currency;
}
public class EtfTicker(string ticker) : IAssetId
{
public string GetSymbol() => ticker;
}
public interface IAssetWorthCalculator<in TAssetId> where TAssetId : IAssetId
{
decimal CalculateWorth(TAssetId assetId);
}
public class MoneyWorthCalculator : IAssetWorthCalculator<Currency>
{
public decimal CalculateWorth(Currency assetId)
{
...
}
}
public class EtfWorthCalculator : IAssetWorthCalculator<EtfTicker>
{
public decimal CalculateWorth(EtfTicker assetId)
{
...
}
}
现在假设我有一个不同资产 ID 的列表,我想计算其总价值。
List<IAssetId> assetIds = [
new Currency("USD"),
new EtfTicker("SPY")
];
decimal worth = TotalWorthCalculator.GetTotalWorth(assetIds);
总价值计算将在如下所示的类中进行:
public class TotalWorthCalculator
{
public decimal GetTotalWorth(IList<IAssetId> assetIds)
{
decimal sum = 0;
foreach (IAssetId id in assetIds)
{
IAssetWorthCalculator<IAssetId> worthCalculator = ???
decimal worth = worthCalculator.CalculateWorth(id);
sum += worth;
}
return sum;
}
}
我正在尝试找出一种实现类的方法,该类为给定的资产 ID 返回适当的价值计算器,例如
问题1: 我无法获得价值计算器的通用类型(在为给定资产 ID 返回正确计算器的类中使用它)。因此,尝试执行以下操作会引发编译器错误(因为 IAssetId 是比 MoneyWorthCalculator 中的货币更基本的类型):
IAssetWorthCalculator<IAssetId> worthCalculator = new MoneyWorthCalculator();
问题2: 每个计算器都有一个CalculateWorth方法,该方法仅接受特定的参数类型,因此MoneyWorthCalculator不会接受IAssetId。
我正在考虑使用非通用版本的价值计算器,但这需要方法参数类型检查,这会打破里氏替换原则:
public class MoneyWorthCalculator : IAssetWorthCalculator
{
public decimal CalculateWorth(IAssetId assetId)
{
if (assetId is not Currency)
{
throw new ArgumentException();
}
return 10;
}
}
我认为你必须阅读工厂模式,它将帮助你根据货币和资产替换类