这是我在金融行业的问题领域:
Asset ========== Asset parent assetID + compareTo(Asset anotherAsset) Portfolio : Asset ----------------- name risk limit List stocks + compareTo(Asset anotherAsset) + composite.CompareTo(Portfolio, ComparisonRules). Stock : Asset ------- market amount company + compareTo(Asset anotherAsset) AnotherStock : Stock -------------------- someOtherProperty + compareTo(Asset anotherAsset)
我已将复合模式应用于 *股票*s 中的 *Portfolio*s 结构。我想要一种干净的方式来自定义此组合的 compareTo 方法。也就是说,AnotherStock 将始终与另一个 AnotherStock、Stocks 与 Stocks 进行比较。这看起来像是我的策略模式。
我想做类似下面的事情(伪代码)
differences = composite.CompareTo(anotherComposite, ComparisonRules). composite.CompareTo would be something like : ComparisonRules.Compare(this.Stocks[currentAssetID], otherComposite[currentAssetID])
ComparisonRules.Compare(Asset a, Asset b) 会做这样丑陋的事情:
if( a is Stock and b is Stock) : convert to stock and do stock-based comparison else if (a is AnotherStock and b is AnotherSTock): convert to AnotherStock
有没有一种编写 ComparisonRules 的方法使我不必向下转换但仍提供自定义 ComparisonRules 对象?
最佳答案
从规则的角度来看,听起来您需要的是泛型。如果您按照以下方式定义某些内容:
public class ComparisonRule<TStock> where TStock : Stock
{
public int Compare(TStock lValue, TStock rValue)
{
...
}
}
这将保证只有等于或低于 TStock
的类型将被接受。例如,如果我有一个 ComparisonRule<AnotherStock>
, 然后只输入等于或低于 AnotherStock
的类型可以传入。但是,如果您希望能够定义一个可以比较 Stock
的规则,您可能需要重新考虑您的类型层次结构。但不是 AnotherStock
.你应该考虑有一个共同的祖先,但具体的种群类型应该在不同的继承树中。
换句话说,你有这个:
Stock
|
--------------------------
| |
OneStock AnotherStock
这将允许您定义一个规则来比较任何 Stock
作为ComparisonRule<Stock>
, 或者只能比较 OneStock
的规则作为ComparisonRule<OneStock>
.
然而,这并不能帮助您理清如何知道哪个 Stock
将对象传递给更高级别的规则。为此,您需要能够定义一个不太具体的版本 ComparisonRule
我们可以用一个界面来做到这一点:
public interface IComparisonRule
{
bool CanCompare(Stock lValue, Stock rValue);
int Compare(Stock lValue, Stock rValue);
}
public abstract class ComparisonRule<TStock> : IComparisonRule where TStock : Stock
{
bool IComparisonRule.CanCompare(Stock lValue, Stock rValue)
{
return lValue is TStock && rValue is TStock;
}
int IComparisonRule.Compare(Stock lValue, Stock rValue)
{
return Compare((TStock)lValue, (TStock)rValue);
}
public abstract int Compare(TStock lValue, TStock rValue);
}
现在,严格来说,您的问题是问如何在不向下转型的情况下做到这一点,这(再次严格来说)是不可能的。但是,这应该使您不必在每次实现时都这样做。例如,比较两个 AnotherStock
的简单规则实例将是:
public class MyRule : ComparisonRule<AnotherStock>
{
public override int Compare(AnotherStock lValue, AnotherStock rValue)
{
return lValue.someOtherProperty.CompareTo(rValue.someOtherProperty);
}
}
在更高级别(即在 Portfolio
内),您可以简单地保留 IComparisonRule
的列表按照你的规则,那么你可以调用CanCompare
并传入两个 Stock
实例以查看它是否是有效比较,然后将它们传递给 Compare
以便进行比较。
关于c# - 想要避免在传递给 Composite 的 Strategy 中向下转型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7135557/