Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带双Typeparam的泛型类型上的何处约束-装箱/取消装箱?_C#_Garbage Collection_Clr - Fatal编程技术网

C# 带双Typeparam的泛型类型上的何处约束-装箱/取消装箱?

C# 带双Typeparam的泛型类型上的何处约束-装箱/取消装箱?,c#,garbage-collection,clr,C#,Garbage Collection,Clr,我有一个类,它的定义如下。接口和具体类型都有一个类型参数,我希望它是double、int、decimal或DateTime。我已经添加了IComparable的where约束,但是这个类做了一些繁重的数字提升,所以我希望避免装箱和拆箱。类别定义如下: public interface INumericClass<T1, T2> where T1:IComparable where T2:IComparable { void DoLongNumericOperati

我有一个类,它的定义如下。接口和具体类型都有一个类型参数,我希望它是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);         
        }     
    } 
} 
美国类中的公共接口,其中T1:i可比较
其中T2:i可比较
{
void DoLongNumericOperation();
}  
公共类NumericClass:INumericClass,其中T1:I可比较
其中T2:i可比较
{     
私有IList_innerArray1=新T1[1000000];
私有IList_innerArray2=新T2[1000000];
公共无效DoLongNumericOperation()
{         
对于(int i=0;i<\u innerray1.Count;i++)
{             
//这里进行一些计算
//例如,它可能是
双常数=123.45;
双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(); 
var numeric=new NumericClass();
numeric.dolongNumericComputing();
现在在内部,我处理多个类型的方法是将T转换为double。然而,我担心的是,因为我已经指定T是IComparable类型的类型param,所以正在进行拆箱/装箱。此外,DateTime还提供了额外的开销。对于这种类型,我要做的是将
.Ticks
属性转换为double并对其进行操作

我欢迎您提供有关CLR中正在发生的事情的任何信息,以及提高性能的建议,例如API更改,以强键入每个数值操作,从而提高性能和内存使用率


Edit:我还应该添加上面的实现是次优的,就像您声明NumericClass它开始从Tx到double进行强制转换一样。我只能假设它是通过IComparable铸造的,尽管我不确定

请参见。

请参见。

如果没有更完整的示例,下面是我可以推荐的

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);
        }
    }
}
公共接口IConvertToDouble
其中T:i可比较
{
双转换(T输入);
T转换回(双输入);
}
公共类数字类
其中T:i可比较,
U:可比
{
私人IConvertToDouble\u tConverter;
私人IConvertToDouble _uConverter;
私人名单;
内部私人名单;
公共数字类(IConvertToDouble tConverter、IConvertToDouble uConverter)
{
_t转换器=t转换器;
_uConverter=uConverter;
_internalTs=新列表();
_internalUs=新列表();
}
公共无效DoLongNumericOperation()
{
for(int i=0;i

现在,您不需要强制转换泛型对象或在NumericClass中使用特定于类型的逻辑。

如果没有更完整的示例,下面是我可以推荐的

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);
        }
    }
}
公共接口IConvertToDouble
其中T:i可比较
{
双转换(T输入);
T转换回(双输入);
}
公共类数字类
其中T:i可比较,
U:可比
{
私人IConvertToDouble\u tConverter;
私人IConvertToDouble _uConverter;
私人名单;
内部私人名单;
公共数字类(IConvertToDouble tConverter、IConvertToDouble uConverter)
{
_t转换器=t转换器;
_uConverter=uConverter;
_internalTs=新列表();
_internalUs=新列表();
}
公共无效DoLongNumericOperation()
{
for(int i=0;i

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

INumericClass
只有一个类型参数。但是,当您将其用于
NumericClass
时,您提供了两个类型参数。哪个是对的?抱歉,我会更新代码片段的质量很低。让它先编译。解释下一步如何进行转换。@HansPassant代码片段旨在传达意图,而不是准确的编译。我几乎不能在这里粘贴我的专有代码,我可以吗?更新。我刚刚将它粘贴到VS中,是的,它非常糟糕:)我将更新代码示例
INumericClass
只有一个类型参数。但是,当您将其用于
NumericClass
时,您提供了两个类型参数。哪个是对的?抱歉,我会更新代码片段的质量很低。让它先编译。解释下一步如何进行转换。@HansPassant代码片段旨在传达意图,而不是准确的编译。我几乎不能在这里粘贴我的专有代码,我可以吗?更新。我刚刚把它粘贴到VS中,是的,它非常糟糕:)我将更新c