实例化泛型类时如何避免指定冗余类型

Posted

技术标签:

【中文标题】实例化泛型类时如何避免指定冗余类型【英文标题】:How to avoid specifying redundant types when instantiating a generic class 【发布时间】:2015-12-09 04:08:41 【问题描述】:

我有一个如下定义的通用接口 (IAmMeasurable)。我有该接口的实现(Sales)。我正在尝试创建一个通用类 (Fact),以便我可以像这样实例化它:

var todaySales = new Fact<Sales>();

不幸的是,我不得不做以下事情:

var todaySales = new Fact<Sales, decimal>();

这似乎很尴尬,因为Sales 被定义为IAmMeasurable&lt;decimal&gt;decimal 隐含在 Sales 的使用中

public interface IAmMeasurable<TValue> where TValue : struct



public class Sales : IAmMeasurable<decimal>



public class Fact<TMeasure, TValue> 
    where TMeasure : IAmMeasurable<TValue> 
    where TValue : struct

    public TValue Observed  get; set; 

也许这只是语言的限制?或者是否有另一种方法来构建它以实现我的目标?还是我根本没有正确考虑问题?

在我看来,有些东西是可衡量的,它们以特定类型衡量(销售额以美元衡量,以小数表示)。事实是对某种度量的观察。我观察到今天的销售额是 100 美元(1 亿)。

【问题讨论】:

Obvioulsy Sales : IAmMeasurable&lt;decimal&gt;, IAmMeasurable&lt;int&gt;, IAmMeasurable&lt;double&gt; 会混淆您的 Fact 如果您正在寻找的内容允许... 啊!我没有意识到一个类可以两次实现相同的接口,提供不同的 TValues。有什么方法可以限制吗? 【参考方案1】:

如果你想避免这种情况,你只需要设计一个中间类,其中TValueFact 是十进制的:

public class DecimalFact<TMeasure> : Fact<TMeasure, decimal>
    where TMeasure : IAmMeasurable<decimal>


即使在第 6 版中,C# 也没有像在方法中发生的泛型类型参数推断。顺便说一句,很难通过使用来推断泛型类型参数。 C# 编译器如何知道IAmMeasurable&lt;T&gt; T 泛型参数是TValue?也许是一些新的通用约束,比如TValue is TMeasure?谁知道;)

似乎上述解决方案是最好的解决方法,也是通过设计具体化泛型参数的最常见解决方案。

【讨论】:

这里 TValuewhere TMeasure : IAmMeasurable&lt;TValue&gt; 中是未知的。将其更改为IAmMeasurable&lt;decimal&gt;

以上是关于实例化泛型类时如何避免指定冗余类型的主要内容,如果未能解决你的问题,请参考以下文章

如何在基类中实例化泛型类型?

Java进阶之泛型

C#泛型 类型约束

在C#中实例化泛型类型的实例

C# 泛型类型参数的约束

限制泛型可用类型,类型通配符声明,泛型方法