Возможно ли вернуть ссылку на переменную в C #?

Могу ли я вернуть ссылку на двойное значение, например?

Это то, что я хочу сделать:

ref double GetElement() { ...... // Calculate x,y,z return ref doubleArray[x,y,z]; } 

Использовать его так

 void func() { GetElement()=5.0; } 

Это похоже на возrotation двойного указателя в C ++ … Я знаю, что способ, которым я его написал, неверен … но есть ли правильный способ сделать это?

Типы значений в C # всегда передаются по значению. Объекты всегда имеют ссылку, переданную по значению. Это изменяется в «небезопасном» коде, как указывает Axarydax.

Самый простой и безопасный способ избежать этого ограничения – убедиться, что ваш двойник каким-то образом привязан к объекту.

 public class MyObjectWithADouble { public double Element {get; set;} // property is optional, but preferred. } ... var obj = new MyObjectWithADouble(); obj.Element = 5.0 

Я также хочу заметить, что я немного смущен тем, как вы ожидаете присвоения двойного трёхмерного массива. Вы можете уточнить, что вы собираетесь делать.

Кажется, я понимаю немного лучше, что вы сейчас делаете. Вы хотите вернуть местоположение значения в заданном массиве и затем изменить значение в этом месте. Этот шаблон нарушает некоторые из ожидаемых парадигм C #, поэтому я бы предложил рассмотреть другие способы достижения того, что вы ищете. Но если это действительно имеет смысл сделать это, я бы сделал нечто подобное:

 public class 3dArrayLocation {public int X; public int Y; public int Z;} ... public 3dArrayLocation GetElementLocation(...) { // calculate x, y, and z return new 3dArrayLocation {X = x, Y = y, Z = z} } ... var location = GetElementLocation(...); doubleArray[location.X, location.Y, location.Z] = 5.0; 

ОБНОВЛЕНИЕ: желаемая функция теперь поддерживается в C # 7.


Система типа CLR поддерживает методы ref-return, и я написал экспериментальный прототип компилятора C #, который поддерживает функцию, которую вы хотите. (Прототип также реализует локализованные локальные переменные, но заполненные поля являются незаконными в системе типа CLR.)

Вы выбрали именно тот синтаксис, который я выбрал для прототипа, что означает, что оба великих ума думают одинаково или что дураки никогда не отличаются друг от друга.

Хотя прототип работает довольно хорошо, маловероятно, что это заставит панель стать отличительной чертой следующей версии языка C #. Очень немногие клиенты хотят эту функцию, ее довольно дорого реализовать, у нас есть список до тех пор, пока у вас есть arm более важных функций, и есть другие способы заставить эту работу работать, не добавляя эту сложность в систему типов. Это все огромные «очки против», делающие эту функцию.

Например, вы можете сделать пару делегатов:

 struct Ref { private readonly Func getter; private readonly Action setter; public Ref(Func getter, Action setter) { this.getter = getter; this.setter = setter; } public T Value { get { return getter(); } set { setter(value); } } } var arr = new int[10]; var myref = new Ref(()=>arr[1], x=>arr[1]=x); myref.Value = 10; Console.WriteLine(myref.Value); 

Это значительно медленнее, чем та же функция, реализованная с возвратом возврата, но преимущество в том, что вы можете сделать Ref в местах, где ref не является законным. Например, вы можете сохранить Ref в поле, которое вы не можете сделать с помощью метода ref-ref.

Если у вас есть действительно удивительный убедительный сценарий, почему вам нужны методы ref-return, я хотел бы услышать об этом. Чем больше реальных сценариев мы имеем, тем более вероятно, что такая функция может быть реализована в гипотетической будущей версии языка.

См. Также связанные вопросы:

Можно ли использовать ссылку внутри функции C #, например C ++?

Почему C # не поддерживает возврат ссылок?

и мой пост в блоге по теме:

http://ericlippert.com/2011/06/23/ref-returns-and-ref-locals/

Нет, это невозможно в C #. Вы можете передавать только параметры по ссылке.

Однако вы можете добиться того же результата с помощью свойства:

 double Element { get { return doubleArray[x,y,z]; } set { doubleArray[x,y,z] = value; } } void func() { Element = 5.0; } 

Вы можете сделать это в небезопасном коде и иметь метод, который возвращает указатель на double:

 unsafe double* GetElementP(){ ... } 

После некоторого размышления, почему бы не отправить значение, которое нужно установить с помощью такой функции:

 void SetElement(double value) { ...... // Calculate x,y,z doubleArray[x,y,z]=value; } 

и использовать его:

 void func() { SetElement(5.0); } 

Тем не менее, я по-прежнему буду выбирать один из ваших полезных ответов …

  • error: неверная инициализация не-const ссылки типа 'int &' из rvalue типа 'int'
  • Причина передачи указателя по ссылке в C ++?
  • Использование в качестве конкретного типа, соответствующего протоколу AnyObject, не поддерживается
  • exit () внутри функции, которая должна возвращать ссылку
  • Qt Linker Error: «неопределенная ссылка на vtable»
  • как знак амперсанда (&) работает в c ++?
  • В чем причина использования двойного указателя при добавлении узла в связанный список?
  • Указатель против ссылки
  • Interesting Posts

    Удалить повторяющиеся записи в PostgreSQL

    Что такое GPT Protective volume в Windows 8 и можно ли их восстановить?

    Проблема SQLiteOpenHelper с полным именем пути к базе данных

    SASS – использование переменных в нескольких файлах

    Маршрутизатор работает медленно, но быстро загружается

    Когда были введенные в C ++ «и» и «или» альтернативные токены?

    Есть ли способ обеспечить, чтобы конкретный USB-ключ всегда получал одну и ту же букву диска?

    Холст растягивается при использовании CSS, но нормальный с свойствами «ширина» / «высота»

    Как я могу извлечь из репозитория Git через HTTP-прокси?

    Создание диаграммы classов UML из Java Project

    Escape символ одиночной кавычки для использования в SQLite-запросе

    Как скопировать дискету для загрузки?

    Один веб-сайт не будет работать на одном компьютере независимо от того, что

    Красные горизонтальные линии в моем ЖК-телевизоре только в черных тонах

    Что означает каждая из деталей в dpkg -l?

    Давайте будем гением компьютера.