C # оператор присваивания ссылки? - PullRequest
4 голосов
/ 21 октября 2011

например:

        int x = 1;
        int y = x;
        y = 3;
        Debug.WriteLine(x.ToString());

Это какой-либо оператор ссылки вместо "=" в строке: 3, чтобы сделать х равным 3, если я назначу у = 3.

Ответы [ 6 ]

9 голосов
/ 21 октября 2011

Я однажды написал прототип версии C #, которая имела эту функцию;Вы можете сказать:

int x = 123;
ref int y = ref x;

и теперь x и y будут псевдонимами для одной и той же переменной.

Мы решили не добавлять эту функцию в язык;если у вас есть действительно потрясающий случай использования, я бы с удовольствием его услышал.

Вы не первый, кто спрашивает об этой функции;см. Могу ли я использовать ссылку внутри функции C #, например, C ++? для получения более подробной информации.

ОБНОВЛЕНИЕ: функция, вероятно, будет в C # 7.

4 голосов
/ 21 октября 2011

'int' является типом значения и поэтому копирует значение при присваивании, как вы обнаружили.

Вы можете использовать указатели в традиционном для C / C ++ смысле, используя небезопасный блок, но тогда указатели можно использовать только внутри этого блока, что ограничивает его использование.Если вместо этого вы хотите получить доступ к значению за пределами «небезопасного» блока, вам нужно вместо этого перейти на использование ссылки.

Что-то вроде этого ...

var x = new Tuple<int>(1);
var y = x;
y.Item1 = 3;
3 голосов
/ 21 октября 2011

Вы можете использовать указатели как в C

    int x = 1;
    unsafe
    {
        int* y = &x;
        *y = 3;
    }

    Debug.WriteLine(x.ToString());

(обратите внимание, что вы должны скомпилировать с небезопасным флагом)

3 голосов
/ 21 октября 2011

Это не совсем то, что вы спрашиваете, но я подумал, что это может быть полезно. Если вам нужен псевдоним указателя внутри функции, вы можете использовать ключевое слово ref, например:

public static void RefExample(ref int y)
{
    y = 3;
}

main()
{
    int x = 5;
    RefExample(ref x);
    Console.WriteLine(x); // prints 3
}
0 голосов
/ 13 сентября 2015

Я хотел прокомментировать ответ Эрика Липперта, но новые пользователи не могут комментировать посты. Итак, я думаю, что у меня есть такое использование.

Посмотрите на этот код:

private void SetGridColumns(ref RegistryKey targetKey, List<ColInfo> cols)
    {
        string targetKeyName = Path.GetFileName(targetKey.Name);
        m_grids.DeleteSubKeyTree(targetKeyName, false);
        targetKey.Close();
        targetKey = m_grids.CreateSubKey(targetKeyName);

// ... }

    public void SetColumns(List<ColInfo> cols, bool youth)
    {
        RegistryKey key = youth ? m_youthGrid : m_mainGrid;
        SetGridColumns(ref key, cols);
    }

Это должно работать так: В SetColumns я вызываю SetGridColumns с ключом в зависимости от параметра «молодежь». Я хотел бы, чтобы мой ключ был сначала удален, а затем воссоздан. m_mainGrid, конечно, является членом класса. В этом случае ключ действительно удаляется и воссоздается. Но воссоздан только "targetKey" в SetGridColumns, а не мой m_mainGrid.

Итак, единственное, что я могу здесь сделать, - это использовать указатели, что не является предпочтительным способом в C #. Если бы я мог только сделать:

ref RegistryKey key = youth ? m_youthGrid : m_mainGrid;

все должно работать нормально.

0 голосов
/ 21 октября 2011

Единственный способ сделать это - использовать «небезопасный» код и фактически использовать указатели. Указатели не могут существовать вне небезопасных блоков кода в C #. После этого вы сможете использовать указатели так же, как в C / C ++

Проверьте на этой странице о том, как использовать «небезопасные» блоки кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...