0

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?

Michael Meadows
  • 27,796
  • 4
  • 47
  • 63
jyotishka bora
  • 3,963
  • 2
  • 23
  • 19
  • Can you provide a code sample of what you are trying to do? – Fredrik Mörk Jun 02 '09 at 19:59
  • 2
    Still waiting for a vote-to-close reason of "questioner wastes everyone's time with a godawfully written question." – mqp Jun 02 '09 at 20:01
  • 1
    Still waiting for someone else to point out Long To Int == overflow ;) – Eoin Campbell Jun 02 '09 at 20:02
  • 1
    Since the intent is far from clear, it's a little hard to edit it for clarity. Any guess as to what the OP wants would probably be wrong. – Michael Meadows Jun 02 '09 at 20:07
  • Creative edit, but how do you know the original poster wasn't actually asking about nullable types? – mqp Jun 02 '09 at 20:17
  • There, OP was diligent enough to accept Jon's answer, but not enough to clarify the question. I did my best to make the question useful. @jyotishka bora, If I didn't do your question justice, please change it. – Michael Meadows Jun 02 '09 at 20:17
  • @mquander, only guessing based on the acceptance of Jon's answer. – Michael Meadows Jun 02 '09 at 20:17
  • @Michael - nice, good thing I checked to see if it was already edited before I submitted mine! – John Rasch Jun 02 '09 at 20:18
  • hey guys...i dont understand. i just asked a simple question.. im not looking for solution to a problem that i have in my code. i was just curious if we can cast a ref int? to ref ?long. and i already got the answer i was looking for, and i accepted the answer.. lets move on... – jyotishka bora Jun 03 '09 at 00:06
  • by the way i wasnt looking for downcasting a long to an int in a method where the long is passed as a ref variable.. – jyotishka bora Jun 03 '09 at 00:08
  • 1
    @jyotishka, you have to understand that even though 1,000,000 monkeys may stumble upon the answer to your question, the question itself isn't clear. It serves no future benefit for the community unless the question can be recast to something that is easy to understand and search. You should probably edit the question yourself to show exactly what you mean. A code sample is very useful in doing that. – Michael Meadows Jun 03 '09 at 13:17

5 Answers5

5

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;
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    I would add that if the OP has control of the method that defines the ref parameter, it should be changed to a return value. I have never seen a situation in managed code where ref variables served any purpose except to make code messy, and induce sloppiness (difficult to trace side-effects). – Michael Meadows Jun 02 '09 at 20:22
  • Do you include "out" parameters in that too? I rather like the TryParse etc pattern. – Jon Skeet Jun 02 '09 at 20:56
  • I'm torn on out variables. It's essentially a second return value, which reeks of bad design (unless it's for interoperability). On the other hand, the problem with side-effects doesn't exist, so it's hard to argue that it is dangerous. Inconsistent yes, dangerous, no. I wonder if they had it to do again (after generics), if the framework team wouldn't have implemented ParseResult as a return value. It would mean an extra line of code for each parse, but it would fit in with framework design better. – Michael Meadows Jun 02 '09 at 21:02
  • As a side note, one of the most interesting extension methods I have seen is: *** public static void IfDecimal(this string toParse, Action toExecute) { decimal d; if (decimal.TryParse(toParse, out d)) toExecute(d); } "5.6".IfDecimal(Console.WriteLine); *** – Michael Meadows Jun 02 '09 at 21:15
3

You don't. You can't take your reference and point it to a different type. How would the code calling your method know that it's changed?

If you just want to work with the value as an int, then you could do something like this:

private void Process(ref long l)
{
    int i = (int)l;
    // do whatever
}
mqp
  • 70,359
  • 14
  • 95
  • 123
1

You're a little light on the details, but if you're talking about this scenario:

public void Something(ref long something)
{
    // code
}

int foo;
Something(ref foo);

try this:

long foo;
Something(ref foo);
int bar = (int) foo;
Michael Meadows
  • 27,796
  • 4
  • 47
  • 63
1

You can't safely cast a long to an int regardless of whether it's nullable or not as theres a chance it will overflow.

try this

        if (!blah.HasValue)
            blah = long.MaxValue;

        int x = (int)blah.Value;

        Console.WriteLine(x); //Not What you expect
Eoin Campbell
  • 43,500
  • 17
  • 101
  • 157
0

You cannot directly cast this. The best option would be to cast it to a local, then assign it at the end of your method.

void Method(ref long myValue)
{
   int tempValue = (int)myValue;
   // change tempValue
   myValue = tempValue;
}
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373