Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic "Scoping" of C# Checked Expression

Is it possible (in C#) to cause a checked(...) expression to have dynamic "scope" for the overflow checking? In other words, in the following example:

int add(int a, int b)
{
    return a + b;
}
void test()
{
    int max = int.MaxValue;
    int with_call = checked(add(max, 1)); // does NOT cause OverflowException
    int without_call = checked(max + 1);  // DOES cause OverflowException
}

because in the expression checked(add(max, 1)), a function call causes the overflow, no OverflowException is thrown, even though there is an overflow during the dynamic extent of the checked(...) expression.

Is there any way to cause both ways to evaluate int.MaxValue + 1 to throw an OverflowException?

EDIT: Well, either tell me if there is a way, or give me a better way to do this (please).

The reason I think I need this is because I have code like:

void do_op(int a, int b, Action<int, int> forSmallInts, Action<long, long> forBigInts)
{
    try
    {
        checked(forSmallInts(a, b));
    }
    catch (OverflowException)
    {
        forBigInts((long)a, (long)b);
    }
}
...
do_op(n1, n2, 
    (int a, int b) => Console.WriteLine("int: " + (a + b)),
    (long a, long b) => Console.WriteLine("long: " + (a + b)));

I want this to print int: ... if a + b is in the int range, and long: ... if the small-integer addition overflows. Is there a way to do this that is better than simply changing every single Action (of which I have many)?

like image 737
feralin Avatar asked Dec 20 '22 01:12

feralin


1 Answers

To be short, no it is not possible for checked blocks or expressions to have dynamic scope. If you want to apply this in the entirety of your code base you should look to adding it to your compiler options.

Checked expressions or checked blocks should be used where the operation is actually happening.

    int add(int a, int b)
    {
        int returnValue = 0;

        try
        {
            returnValue = checked(a + b);
        }
        catch(System.OverflowException ex)
        {
            //TODO: Do something with exception or rethrow
        }

        return returnValue;
    }

    void test()
    {
        int max = int.MaxValue;
        int with_call = add(max, 1);
    }
like image 145
Tylerflick Avatar answered Jan 01 '23 16:01

Tylerflick