3

在 C# 中,是不可能在 int 和 uint 上工作的泛型方法,因为泛型类型必须是类而不是原始类型,或者这仅适用于约束?

public decimal shift<T>(T input, byte b) where T : int, uint
{
   ///....
}

无论如何,是否可以在没有限制的情况下完成这项工作?

public decimal shift<T>(T input, byte b)  
{
   ///....
}

当我做后者时,我会在 int 或 uint 上的位移操作上得到进一步但仍然出错。就好像,它在运行时不知道它是什么类型。

4

3 回答 3

2

在 C# 中,为本地类型编写特殊情况通常通过方法重载来完成。BCL 中有几个地方可以看到这种设计,一个例子就是BitConverter类。

如果您想要一个带有一些特殊情况的通用版本,您可以添加一个通用重载,C# 的类型推断将使其对最终用户透明。

public decimal shift(int input, byte b)
{
    //....
}

public decimal shift(uint input, byte b)
{
    //....
}

public decimal shift<T>(T input, byte b)
{
    //....
}

用法:

shift(5, 1); //resolves to the 'int'overload
shift(5u, 1); //resolves to the 'uint' overload
shift(new Point(2, 2), 1) //resolves to the generic overload with T = Point

我猜您正在尝试使用通用方法进行位移。只有少数类型是有意义的(byte、sbyte、short、ushort、int、uint、long、ulong),所以你不妨写出这 8 个重载。我的一个项目中有一个课程,其中包含很多技巧,我只写了必要的重载,效果很好。

于 2013-07-02T04:48:24.243 回答
0

您必须使用以下代码才能使其正常工作:

    public static decimal shift<T>(T input, byte b) where T : struct
    {
        return 1.0M;
    }

这是因为 int 和 uint 是结构而不是类

于 2013-07-02T04:24:43.207 回答
0

我认为在这种情况下,您必须在运行时检查它的类型,但如果您只需要重载采用 int 和 uint 的方法会更清楚

public decimal shift<T>(T input, byte b)
{ 
    if (input is int)
        return (Convert.ToInt32(input) << b);
    else if (input is uint)
        return (Convert.ToByte(input) << b);
}

对比

public decimal shift(int input, byte b)
{ 
    return input << b;
}

public decimal shift(uint input, byte b)
{
    return input << b;
}
于 2013-07-02T04:39:50.893 回答