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

本文关键字:冗余 类型 实例化 泛型类 | 更新日期: 2023-09-27 18:12:25

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

var todaySales = new Fact<Sales>();

不幸的是,我不得不这样做:

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

这似乎很尴尬,因为Sales被定义为IAmMeasurable<decimal>Sales

的使用暗示了decimal
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美元。

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

如果您想避免这种情况,您只需设计一个中间类,其中FactTValue为十进制:

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

即使在它的第6个版本中,c#也没有像在方法中那样的泛型类型参数推断。顺便说一句,很难通过用法推断出泛型类型参数。c#编译器如何知道IAmMeasurable<T> T泛型参数是TValue ?也许是一些新的通用约束,比如TValue is TMeasure ?谁知道呢;)

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