带有Double Typeparam的泛型类型上的Where约束-装箱/取消装箱

本文关键字:装箱 取消装箱 约束 Double Typeparam 泛型类型 带有 Where | 更新日期: 2023-09-27 18:26:23

我有一个类,它是以以下方式定义的。接口和具体类型都有一个type Parameter,我希望它是double、int、decimal或DateTime。我添加了IComparable的where约束,但是这个类做了一些繁重的数字提升,所以我想避免装箱和取消装箱。类别定义如下:

public interface INumericClass<T1, T2>  where T1:IComparable 
    where T2:IComparable
{
    void DoLongNumericOperation();
}  
public class NumericClass<T1, T2> : INumericClass<T1, T2> where T1:IComparable 
    where T2:IComparable 
{     
    private IList _innerArray1 = new T1[1000000];
    private IList _innerArray2 = new T2[1000000];      
    public void DoLongNumericOperation()     
    {         
        for(int i = 0; i < _innerArray1.Count; i++)         
        {             
            // some computation goes on in here             
            // for example, it could be             
            double aConstant = 123.45;
            double aScalar = 56.7;
            _innerArray1[i] = (Convert.ToDouble(_innerArray1[i]) * aConstant + aScalar);
            _innerArray2[i] = (Convert.ToDouble(_innerArray2[i]) * aConstant + aScalar);         
        }     
    } 
} 

这些类将被声明并用于调用代码,如下所示

var numeric = new NumericClass<int, double>();
numeric.DoLongNumericComputation(); 

现在,在内部,我处理多个类型的方法是将T强制转换为double。然而,我担心的是,由于我已经指定T是IComparable类型的类型参数,因此正在进行开箱/装箱。此外,DateTime还提供了额外的开销。在这种类型的情况下,我要做的是将.Ticks属性转换为double并对其进行操作。

我欢迎任何关于CLR中到底发生了什么的信息,以及提高性能的建议,例如API更改为强类型每个数字操作以提高性能和内存使用率。

编辑:我还应该添加上面的实现是次优的,就像你声明NumericClass一样,它开始在从Tx到double的转换中抛出。我只能通过IComparable来假设它的选角,尽管我不确定。

带有Double Typeparam的泛型类型上的Where约束-装箱/取消装箱

在没有看到更完整的示例的情况下,我可以推荐以下内容。

public interface IConvertToDouble<T>
   where T : IComparable
{
    double Convert(T input);
    T ConvertBack(double input);
}
public class NumericClass<T, U>
    where T : IComparable,
          U : IComparable
{
    private IConvertToDouble<T> _tConverter;
    private IConvertToDouble<U> _uConverter;
    private List<T> _internalTs;
    private List<U> _internalUs;
    public NumericClass(IConvertToDouble<T> tConverter, IConvertToDouble<U> uConverter)
    {
        _tConverter = tConverter;
        _uConverter = uConverter;
        _internalTs = new List<T>();
        _internalUs = new List<U>();
    }
    public void DoLongNumericOperation()
    {
        for(int i = 0; i < innerArray.Length; i++)
        {
            // some computation goes on in here
            // for example, it could be
            double aConstant = 123.45;  
            double aScalar = 56.7
            _internalTs[i] = _tConverter.ConvertBack(_tConverter.Convert(_internalTs[anIndex]) * aConstant + aScalar);
            _internalUs[i] = _uConverter.ConvertBack(_uConverter.Convert(_internalUs[anIndex]) * aConstant + aScalar);
        }
    }
}

现在,您不需要强制转换泛型对象,也不需要在NumericClass中具有类型特定的逻辑。

请参阅泛型运算符。