Search code examples
c#.netcastingref-parameters

How to downcast a ref variable within the method


I need to downcast a long to an int in a method where the long is passed as a ref variable:

public void Foo(ref long l)
{
    // need to consume l as an int
}

How can I easily do this?


Solution

  • You can't. However, any value you want to put into a ref int can be put into a ref long anyway - you've just got to worry about the initial value, and what you want to do if it's outside the range of int.

    How many places do you need to write to the ref parameter or read it within your code? If it's only in one or two places, you should be okay just to cast appropriately at the right times. Otherwise, you might want to introduce a new method:

    public void Foo(ref int x)
    {
        // Here's the body I *really* want
    }
    
    public void Foo(ref long x)
    {
        // But I'm forced to use this signature for whatever
        // reasons. Oh well. This hack isn't an *exact* mimic
        // of ref behaviour, but it's close.
    
        // TODO: Decide an overflow policy
        int tmp = (int) x;
        Foo(ref tmp);
        x = tmp;
    }
    

    The reason I say in the comments that it's not an exact mimic for the behaviour is that normally changes to the original ref parameter are visible even before the method returns, but now they'll only be visible at the very end. Also, if the method throws an exception, the value won't have been changed. The latter could be fixed with try/finally, but that's a bit clunky. In fact, if you want the try/finally behaviour you can do it all in a single method easily:

    public void Foo(ref long x)
    {
        int y = (int) x;
        try
        {
            // Main body of code
        }
        finally
        {
            x = y;
        }
    }