我很难确定使用checked
的{{1}}上的int
操作是否导致上溢或下溢。如果我不使用Func<int, int>
我找到了确定此方法的方法
Func<int, int>
虽然如果我使用int _Data = Data; // Data is some integer value
int scaleValue = int.MaxValue; // Just for completion, could be any value
try
{
checked
{
Data *= scaleValue;
}
}
catch (System.OverflowException ex)
{
// Cast the values to float so we can operate beyond the integer range
// This way we can check if we went over Max or Min Values
if ((float)_Data * (float)scaleValue > int.MaxValue)
Data = int.MaxValue;
else
Data = int.MinValue;
}
,那么我就无法使用上面的技巧来确定结果。
Func<int, int>
我看到的唯一选择是“更改”给定int _Data = Data;
Func<int, int> scaleFunction = (x) => (x * int.MaxValue);
try
{
checked
{
Data = scaleFunction(Data);
}
}
catch (System.OverflowException ex)
{
// How to tell if scaleFunction created under or over flow?
if ((float)_Data * (float)scaleValue > int.MaxValue)
Data = int.MaxValue;
else
Data = int.MinValue;
}
以便Func<int, int>
工作,但如果float
的结构未知,那么我不认为它可以改变。
任何人都可以通过偷偷摸摸的方式来实现这一目标吗?
这是我找到原始偷偷摸摸的操作的主题:Determine if integer overflow is over or under bounds
这是我之前提到的一个相关问题,它提供了更多背景知识:Determine if operation will result in overflow?
编辑:在我对此代码的使用中,我无法控制Func<int, int>
的创建方式。因此,我不能在其中放置Func<int, int>
表达式或阻止它。
我也没有意识到check
没有检查其中使用的“内部函数”溢出。如果是这样,我认为这个问题要困难得多。由于无法修改check
以使用Func
,我们必须手动进行检查。
手工操作的问题在于(目前对我来说) 似乎不可能 。使用检查原始值是否与check
的输出值具有相同符号的技巧可能是有意义的。问题是,您无法判断Func
是否非法地增加了超过最大值的值,或者是否合法地将值降低到0以下;或者反之亦然。
答案 0 :(得分:4)
在我对这段代码的使用中,我无法控制Func的创建方式。因此,我无法在其中放置检查表达式或阻止它。
然后,你输了。
checked/unchecked
是IL级别的任何单个算术指令的属性。它不会跨越方法调用。它不是可以打开或关闭的设置。它分别编译为每个指令的.NET二进制文件。
任何一段代码的作者都会决定checked
属性,并且不能更改。
事实上,如果你能够达到其他人的代码并巧妙地改变基本算术指令的行为,那将是危险和不可靠的。
答案 1 :(得分:1)
checked
块或表达式(两种口味都存在并且具有相同的效果)不是&#34;继承&#34;通过调用方法,所以你的lambda实际上在未经检查的上下文中成倍增加。
请尝试以下方法:
int _Data = Data;
Func<int, int> scaleFunction = (x) => checked(x * int.MaxValue);
try
{
Data = scaleFunction(Data);
}
catch (System.OverflowException ex)
{
// handle overflow...
}