获取分配给给定对象类型的泛型类

问题描述 投票:0回答:1

我正在编写一个 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 返回适当的价值计算器,例如

  • 如果资产 ID 是货币,则该类返回 MoneyWorthCalculator 对象
  • 如果资产ID是ETF,则返回EtfWorthCalculator

问题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;
    }
}
c# generics contravariance
1个回答
0
投票

我认为你必须阅读工厂模式,它将帮助你根据货币和资产替换类

© www.soinside.com 2019 - 2024. All rights reserved.