Как уменьшить переменную ref внутри метода - PullRequest
0 голосов
/ 02 июня 2009

Мне нужно уменьшить long до int в методе, где long передается как переменная ref:

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

Как я могу легко это сделать?

Ответы [ 5 ]

5 голосов
/ 03 июня 2009

Вы не можете. Тем не менее, любое значение, которое вы хотите поместить в ref int, можно в любом случае поместить в ref long - вам просто нужно беспокоиться о начальном значении и о том, что вы хотите сделать, если оно выходит за пределы диапазона int .

Сколько мест вам нужно записать в параметр ref или прочитать его в вашем коде? Если это только в одном или двух местах, у вас должно быть все в порядке, чтобы правильно разыграть в нужное время. В противном случае вы можете ввести новый метод:

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;
}

Причина, по которой я говорю в комментариях, что это не точная имитация поведения, заключается в том, что обычно изменения исходного параметра ref видны даже до возврата метода, но теперь они будут видны только в самом конце. Также, если метод выдает исключение, значение не будет изменено. Последний можно исправить с помощью try / finally, но это немного неуклюже. На самом деле, если вам нужно поведение try / finally, вы можете легко сделать все это одним методом:

public void Foo(ref long x)
{
    int y = (int) x;
    try
    {
        // Main body of code
    }
    finally
    {
        x = y;
    }
}
3 голосов
/ 02 июня 2009

Ты не. Вы не можете взять свою ссылку и указать ее на другой тип. Как код, вызывающий ваш метод, узнает, что он изменился?

Если вы просто хотите работать со значением как int, то вы можете сделать что-то вроде этого:

private void Process(ref long l)
{
    int i = (int)l;
    // do whatever
}
1 голос
/ 03 июня 2009

Вы не можете безопасно приводить long к int независимо от того, является ли оно обнуляемым или нет, так как есть вероятность, что оно переполнится.

попробуйте это

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

        int x = (int)blah.Value;

        Console.WriteLine(x); //Not What you expect
1 голос
/ 02 июня 2009

Вы немного разбираетесь в деталях, но если вы говорите об этом сценарии:

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

int foo;
Something(ref foo);

попробуйте это:

long foo;
Something(ref foo);
int bar = (int) foo;
0 голосов
/ 02 июня 2009

Вы не можете напрямую разыграть это. Лучшим вариантом будет привести его к локальному, а затем назначить в конце вашего метода.

void Method(ref long myValue)
{
   int tempValue = (int)myValue;
   // change tempValue
   myValue = tempValue;
}
...