是否可以在 运行 时间检测到当前的 unchecked/checked 算术上下文?
Is it possible to detect at run-time the current unchecked/checked arithmetic context?
我可以用这样的东西来检查...
private static readonly int IntMaxValue = int.Parse(int.MaxValue.ToString());
private static bool IsChecked()
{
try {
var i = (IntMaxValue + 1);
return false;
}
catch (OverflowException) {
return true;
}
}
...但是在一个紧密的循环中,这是一个很大的开销,抛出和捕获只是为了检测它。有更简单的方法吗?
编辑更多上下文...
struct NarrowChar
{
private readonly Byte b;
public static implicit operator NarrowChar(Char c) => new NarrowChar(c);
public NarrowChar(Char c)
{
if (c > Byte.MaxValue)
if (IsCheckedContext())
throw new OverflowException();
else
b = 0; // since ideally I don't want to have a non-sensical value
b = (Byte)c;
}
}
如果答案只是 'no',不要害怕简单地说:)
所以答案似乎是 'no',但我找到了针对我的特定问题的解决方案。它可能对最终遇到这种情况的其他人有用。
public NarrowChar(Char c) {
var b = (Byte)c;
this.b = (c & 255) != c ? (Byte)'?' : b;
}
首先,我们 "probe" 通过尝试转换 checked/unchecked 上下文。如果我们被检查,溢出异常会被 (Byte) c
抛出。如果我们未选中,位掩码和与 c
的比较会告诉我们在转换中是否存在溢出。在我们的特定情况下,我们希望 NarrowChar
的语义使得不适合 Byte
的 Char
设置为 ?
;就像将 ™
的 String
转码为 ISO-8759-1 或 ASCII 一样,您会得到 ?
.
首先进行转换对语义很重要。内联 b
会破坏 "probing" 行为。
我可以用这样的东西来检查...
private static readonly int IntMaxValue = int.Parse(int.MaxValue.ToString());
private static bool IsChecked()
{
try {
var i = (IntMaxValue + 1);
return false;
}
catch (OverflowException) {
return true;
}
}
...但是在一个紧密的循环中,这是一个很大的开销,抛出和捕获只是为了检测它。有更简单的方法吗?
编辑更多上下文...
struct NarrowChar
{
private readonly Byte b;
public static implicit operator NarrowChar(Char c) => new NarrowChar(c);
public NarrowChar(Char c)
{
if (c > Byte.MaxValue)
if (IsCheckedContext())
throw new OverflowException();
else
b = 0; // since ideally I don't want to have a non-sensical value
b = (Byte)c;
}
}
如果答案只是 'no',不要害怕简单地说:)
所以答案似乎是 'no',但我找到了针对我的特定问题的解决方案。它可能对最终遇到这种情况的其他人有用。
public NarrowChar(Char c) {
var b = (Byte)c;
this.b = (c & 255) != c ? (Byte)'?' : b;
}
首先,我们 "probe" 通过尝试转换 checked/unchecked 上下文。如果我们被检查,溢出异常会被 (Byte) c
抛出。如果我们未选中,位掩码和与 c
的比较会告诉我们在转换中是否存在溢出。在我们的特定情况下,我们希望 NarrowChar
的语义使得不适合 Byte
的 Char
设置为 ?
;就像将 ™
的 String
转码为 ISO-8759-1 或 ASCII 一样,您会得到 ?
.
首先进行转换对语义很重要。内联 b
会破坏 "probing" 行为。