Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.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# 将常规参数转换为整数或从整数转换为常规参数_C#_Generics_Casting - Fatal编程技术网

C# 将常规参数转换为整数或从整数转换为常规参数

C# 将常规参数转换为整数或从整数转换为常规参数,c#,generics,casting,C#,Generics,Casting,我想编写一个泛型类,该类用于处理内置类型,如byte和ushort。在内部计算中,我需要将泛型类型转换为整数,然后再转换回泛型类型。我找到了编译此类代码的方法,例如: class Test<T> where T : struct, IConvertible { public static T TestFunction(T x) { int n = Convert.ToInt32(x); T result = (T)Convert.Cha

我想编写一个泛型类,该类用于处理内置类型,如
byte
ushort
。在内部计算中,我需要将泛型类型转换为整数,然后再转换回泛型类型。我找到了编译此类代码的方法,例如:

class Test<T> where T : struct, IConvertible
{
    public static T TestFunction(T x)
    {
        int n = Convert.ToInt32(x);
        T result = (T)Convert.ChangeType(n, typeof(T));
        return result;
    }
}
类测试,其中T:struct,IConvertible
{
公共静态测试函数(TX)
{
int n=转换为32(x);
T结果=(T)Convert.ChangeType(n,typeof(T));
返回结果;
}
}

我认为,如果在计算循环中使用这种转换,可能会显著降低性能。有没有更好的方法进行这些转换?

经过思考,我很高兴由于这个问题和一些答案,我解决了我的一个老问题:在泛型T上使用操作:

首先是Cast示例(根据OP的要求)

在一般情况下,乘法速度比直接乘法慢3倍(在释放模式下,无调试)

显然,从乘法开始做其他运算很简单


(有趣的是,我非常熟悉
表达式
树,但我从未想过使用静态类作为包含各种类型的“字典”。我总是做类似
字典
的事情,而不是让.NET通过泛型类专门化来“处理”字典。)
int
T
的转换有点棘手。我想你可以在这里使用
Expression
class

Test
类应该是这样的:

class Test<T> where T : struct, IConvertible
{
    private static Func<int, T> _getInt;

    static Test()
    {
        var param = Expression.Parameter(typeof(int), "x");
        UnaryExpression body = Expression.Convert(param, typeof(T));
        _getInt = Expression.Lambda<Func<int, T>>(body, param).Compile();
    }

    public static T TestFunction(T x)
    {
        int n = Convert.ToInt32(x);
        T result = _getInt(n);
        return result;
    }
}
类测试,其中T:struct,IConvertible
{
私有静态函数;
静态测试()
{
var param=表达式参数(typeof(int),“x”);
UnaryExpression body=Expression.Convert(param,typeof(T));
_getInt=Expression.Lambda(body,param.Compile();
}
公共静态测试函数(TX)
{
int n=转换为32(x);
T结果=_getInt(n);
返回结果;
}
}

它在静态构造函数中为您准备
\u getInt=x=>(T)x
,并在以后使用它,将
int
转换为
T

这方面的性能基准是什么,否则需要改进哪些人?更不用说你怎么知道这是一个真正的问题了。@GrantThomas-包括
Convert.ToInt32
Convert.ChangeType
accept
Object
参数。这意味着,此代码需要装箱。我可以用另一种方式问这个问题:有可能避免装箱吗?你可以,甚至可以使装箱更快,但这仍然不是问题。不管怎样,net对32位整数进行了优化。看得很有趣。动态击败拳击?我现在正在测试这个,谢谢。@AlexFarber我没有做过任何纯拳击方法。不能完全取消绑定到其他类型。如果
T是长的
,并且
tx
(int)(object)x
是无效的异常。试试
intres=(int)(object)5L
真的很有趣。令人惊讶的是,使用
dynamic
可以获得与使用Convert函数相同的性能。使用表达法会有更好的表现,谢谢。我希望接受你的答案,特别是在奇怪的否决票之后,但你用你自己问题的答案取代了它:)我放弃投票,接受另一个答案。希望本次讨论能对SO用户有所帮助。谢谢,使用预编译lambda可以提高函数性能。我还将预编译lambda在另一个方向(T到int)匹配,并在直方图计算方面获得了显著的性能提升。这将减少50%以上的执行时间!直方图函数在装箱上浪费了大部分时间,这是Convert.ToInt32和Convert.ChangeType函数的一部分。这真的很有趣!稍后我会亲自做一些测试!在您的测试套件中,
T
是什么类型?因为
Convert.ToInt32
有一个重载,它以
byte
作为参数,所以这里应该没有装箱。好的,我知道这里发生了什么。实际上,
Convert.ToInt32(byte)
byte.ToInt32
好得多!
public static class Multiply<T>
{
    public static readonly Func<T, T, T> Do;

    static Multiply()
    {
        var par1 = Expression.Parameter(typeof(T));
        var par2 = Expression.Parameter(typeof(T));

        Do = Expression.Lambda<Func<T, T, T>>(Expression.Multiply(par1, par2), par1, par2).Compile();
    }
}
int x = Conv<T, int>.Do(someTValue);
T res = Multiply<T, T>.Do(someTValue1, someTValue2);
class Test<T> where T : struct, IConvertible
{
    private static Func<int, T> _getInt;

    static Test()
    {
        var param = Expression.Parameter(typeof(int), "x");
        UnaryExpression body = Expression.Convert(param, typeof(T));
        _getInt = Expression.Lambda<Func<int, T>>(body, param).Compile();
    }

    public static T TestFunction(T x)
    {
        int n = Convert.ToInt32(x);
        T result = _getInt(n);
        return result;
    }
}