Возможно ли вернуть ссылку на переменную в 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); } 

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

  • int vs const int &
  • «Не удается найти проект или библиотеку» для стандартных функций VBA
  • Множественное определение встроенных функций при связывании статических библиотек
  • error: неверная инициализация не-const ссылки типа 'int &' из rvalue типа 'int'
  • Использование в качестве конкретного типа, соответствующего протоколу AnyObject, не поддерживается
  • В чем разница между SoftReference и WeakReference в Java?
  • Ссылка на объект требуется для нестатического поля, метода или свойства?
  • Делегат Func с переменной ref
  • Interesting Posts

    FFMPEG (libx264) “высота не делится на 2”

    Почему я не могу открыть Windows 7 после установки xp на другой диск?

    Фиксация сеанса в ASP.NET

    Команда TC через веб-страницу как sudo

    AlertDialog с пользовательским представлением: изменение размера, чтобы обернуть содержимое представления

    Как я могу вернуть анонимный тип из метода?

    Задача не сериализуема: java.io.NotSerializableException при вызове функции закрытие только для classов не объектов

    % date% производит разные результаты в пакетном файле при запуске из запланированных задач на сервере 2016

    Необходимо удалить все файлы с одним расширением на диске в Windows 7

    Как получить документы в каталоге Android, которые PhoneGap увидит

    Активность Android по блокировке блокировки по умолчанию

    Как использовать метод отражения для вызова по имени

    Сохранение и извлечение изображения (двоичного) из SQL Server с использованием Entity Framework 6

    Отображение Caps Lock для Escape и управления в Windows 7

    64-разрядные назначения в Java-атоме на 32-битной машине?

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