我正在写一个代表LED的课程。基本上r,g和b的3 uint
值在0到255范围内。
我是C#的新手,并以uint 1 开头,这比我想要的大8位。在编写我自己的Clamp方法之前,我在网上找了一个,发现this great looking answer建议使用扩展方法。问题是它无法推断出类型为uint
。为什么是这样?这段代码已经写完了uint。我必须明确地给出类型以使其有效。
class Led
{
private uint _r = 0, _g = 0, _b = 0;
public uint R
{
get
{
return _r;
}
set
{
_r = value.Clamp(0, 255); // nope
_r = value.Clamp<uint>(0, 255); // works
}
}
}
// https://stackoverflow.com/a/2683487
static class Clamp
{
public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
{
if (val.CompareTo(min) < 0) return min;
else if (val.CompareTo(max) > 0) return max;
else return val;
}
}
1 一个错误,使用byte
是理所当然的。但我仍然对这个问题的答案感兴趣。
答案 0 :(得分:22)
这是因为您使用的是0
和255
,它们是int
值,而不是uint
个值。 C#中的裸整数始终被视为int
值(如果它们在int
范围内)。
您正在使用Clamp
形式调用uint.Clamp(int, int) => uint
。这由编译器转换为Clamp(unit, int, int) => uint
。虽然编译器实际上期望Clamp(T, T, T) => T
,但它会报告错误,因为uint
和int
类型的混合会阻止它解析T
应该采用的类型。
更改行:
_r = value.Clamp(0, 255);
为:
_r = value.Clamp(0U, 255U);
代码将编译。 U
后缀告诉编译器该数字是uint
值。
答案 1 :(得分:21)
其他答案是正确的,但这里有一个微妙的观点,我认为应该特别提出。
通常在C#中,整数文字的类型为int
,但它可以隐式转换为常量在范围内的任何数字类型。因此,即使int
无法隐式转换为uint
,分配myuint = 123;
也是合法的,因为int
适合。
从这个事实可以很容易地认为int
文字可以用在预期uint
的任何地方,但你已经发现了为什么这种信念是错误的。
类型推断算法是这样的。 (这当然是一个大规模的简化; lambdas使这变得更加复杂。)
然后重载分辨率继续比较候选集中的方法以找到最佳方法。
(注意,当然没有考虑返回类型; C#检查在重载决策选择方法之后是否可以将返回类型分配给分配给的任何类型,而不是在过载期间分辨率。)
在您的情况下,类型推断在“验证存在一组一致的边界”步骤中失败。 T
与int
和uint
都有约束力。这是一个矛盾,因此该方法永远不会被添加到用于考虑重载决策的方法集中。从未考虑int
参数 可转换为uint
的事实;类型推理引擎仅适用于类型。
类型推断算法也不会在您的场景中以任何方式“回溯”;它没有说“好的,我无法推断T
的一致类型,但也许其中一种类型有效。如果我尝试了两个边界int
和uint
怎么办?可以看出他们中的任何一个是否真的产生了一种有效的方法。“ (做做类似于涉及lambdas时的事情,这可能导致它在某些情况下尝试任意多种类型的类型组合。)如果推理算法以这种方式工作,那么你会得到结果你渴望,但事实并非如此。
基本上,这里的哲学是类型推理算法并不寻求找到使程序工作的任何方式,而是找到关于派生唯一的类型的推理链来自参数的信息的逻辑结论。 C#尝试做用户意味着做的事情,但也试图避免猜测;在这种情况下,而不是可能猜错,它需要你清楚你想要推断的类型。
答案 2 :(得分:16)
您使用参数Clamp<T>(T, T, T)
致电uint, int, int
(0
和255
为int
文字)。
由于从一种类型到另一种类型没有implicit conversion,编译器无法确定是否要T
int
或uint
。
答案 3 :(得分:4)
当整数文字没有后缀时,其类型是这些类型中的第一个,其值可以表示为:int,uint,long,ulong。你正在使用0和255,它很好地进入int
,因此选择了一个。
您可以通过添加文字
来告诉编译器使用uint
_r = value.Clamp(0U, 255U);
可以从documentation找到更多信息。