C# 重载+;运算符,因此它对在选中或未选中的上下文中被调用很敏感
更新:我找到了答案,如果没有其他人找到,我会在几天后发布C# 重载+;运算符,因此它对在选中或未选中的上下文中被调用很敏感,c#,operator-overloading,unchecked,C#,Operator Overloading,Unchecked,更新:我找到了答案,如果没有其他人找到,我会在几天后发布 我正在创建一个数字结构,因此我正在重载算术运算符。以下是表示4位无符号整数的结构示例: public struct UInt4 { private readonly byte _value; private const byte MinValue = 0; private const byte MaxValue = 15; public UInt4(int value) { i
我正在创建一个数字结构,因此我正在重载算术运算符。以下是表示4位无符号整数的结构示例:
public struct UInt4
{
private readonly byte _value;
private const byte MinValue = 0;
private const byte MaxValue = 15;
public UInt4(int value)
{
if (value < MinValue || value > MaxValue)
throw new ArgumentOutOfRangeException("value");
_value = (byte) value;
}
public static UInt4 operator +(UInt4 a, UInt4 b)
{
return new UInt4((a._value + b._value) & MaxValue);
}
}
这里,计算溢出,因此变量z的值为5
。然而,我也希望能够做到这一点:
var x = new UInt4(10);
var y = new UInt4(11);
var z = checked ( x + y );
此示例应抛出OverflowException。我怎样才能做到这一点
我已经确定,选中的上下文不会扩展到被调用的方法,因此,例如,无论它是在选中的上下文中调用还是在未选中的上下文中调用,都不会抛出:
public static UInt4 operator +(UInt4 a, UInt4 b)
{
int i = int.MaxValue;
//this should throw in a checked context, but when
//the operator is used in a checked context, this statement
//is nonetheless unchecked.
byte b = (byte)i;
return new UInt4((a._value + b._value) & MaxValue);
}
有没有办法声明加法运算符的两个重载,一个是选中的,另一个是未选中的?或者,是否有一种方法可以在运行时确定调用方的上下文(这似乎不太可能,但我想我还是会问),如下所示:
public static UInt4 operator +(UInt4 a, UInt4 b)
{
byte result = (byte)(a._value + b._value);
if (result > MaxValue)
if (ContextIsChecked())
throw new OverflowException();
else
result &= MaxValue;
return new UInt4(result);
}
private static bool ContextIsChecked()
{
throw new NotImplementedException("Please help.");
}
,选中的
和未选中的关键字仅适用于。因此,您不能创建自己的类型来使用选中和未选中的关键字。Close,so+1,但我不会接受这个答案,因为第一页上没有指定“内置整数类型”。我试图定义自己的整型,这就是为什么我希望它对选中/未选中的上下文敏感。换句话说,在第一页应该有一个指向内置整型文档的显式链接,但是没有,所以我觉得这个页面不明确。我找到了一个明确的来源,我会接受第一个引用它的答案。我想我明白了。这是因为您没有重写隐式转换运算符,并允许它转换为一种内置的整数类型,如。尽管我在MSDN上找不到明确的说明,但我猜这与Eric Lippert在文章底部解释的switch语句的工作原理类似。哦,不,根本不是这样。正确答案是“您不能创建自己的类型…”。考虑一下:如果我创建了一个到内置整数类型的隐式转换运算符,我将根据内置整数类型的范围(而不是我试图定义的类型的范围)进行溢出检查。您链接到的SO线程中的示例在未经检查的上下文中溢出时不会翻滚。或者更确切地说,它在未经检查的上下文中转换时不会表现出应有的行为,因为在未经检查的上下文中不可能抛出异常。@JohnSaunders如果为了论证起见,我们假设大象可以飞行,我们无法推断我们假想世界中的大象不是大象,因为现实世界中的大象不会飞。同样,如果有人问你“这辆10号巴士能带我去市政厅吗?”回答“不”比回答“如果那辆巴士存在,它就不会是这辆10号巴士”更有帮助。2003年,我可能会问在可验证代码中使用sizeof(int)
,你会说“你建议的语言不是C”。但现在我们可以这样做了——这是否意味着C#5不是C#?这里有一个答案说这或多或少是不可能的。。。等着看你的方法…@AlexeiLevenkov我找到的答案也表明这是不可能的。我想到的一种方法是定义UInt4Checked
和UInt4Unchecked
类型,并在它们之间进行显式转换。Downvoter,请解释一下。投票结束不是一个真正的问题。你显然是为了说明问题,而不是为了找到答案。找一个博客。@Guffa事实上,我发布这个问题是为了找到答案,然后在发布15分钟后,我对在哪里寻找答案有了另一个想法,我找到了答案。不管怎样,stackoverflow鼓励人们发布他们已经知道答案的问题(尽管这里没有发生这种情况),并自己回答。看见
public static UInt4 operator +(UInt4 a, UInt4 b)
{
byte result = (byte)(a._value + b._value);
if (result > MaxValue)
if (ContextIsChecked())
throw new OverflowException();
else
result &= MaxValue;
return new UInt4(result);
}
private static bool ContextIsChecked()
{
throw new NotImplementedException("Please help.");
}