I could use something like this to check...
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;
}
}
... but that's a lot of overhead in a tight loop, throwing and catching just to detect it. Is there a lighter way to do this?
EDIT for more context...
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;
}
}
If the answer is just 'no', don't be afraid to simply say that :)
So the answer seems to be 'no', but I figured out the solution for my particular problem. It could be useful to someone else who ends up in this situation.
public NarrowChar(Char c) {
var b = (Byte)c;
this.b = (c & 255) != c ? (Byte)'?' : b;
}
First we "probe" the checked/unchecked context by just trying the cast. If we're checked, the overflow exception is thrown by the (Byte) c
. If we're unchecked, the bit mask and comparison to c
tells us if there was an overflow in the casting. In our particular case, we want the semantics of NarrowChar
such that a Char
that won't fit in a Byte
gets set to ?
; just like if you transcode a String
of ™
to ISO-8759-1 or ASCII you get ?
.
Doing the cast first is important to the semantics. Inlining b
will break that "probing" behaviour.