Этот вопрос был темой моего блога 23 июня 2011 года . Спасибо за отличный вопрос!
Команда C # рассматривает это для C # 7. Подробнее см. https://github.com/dotnet/roslyn/issues/5233.
ОБНОВЛЕНИЕ: функция добралась до C # 7!
Вы правы; .NET поддерживает методы, которые возвращают управляемые ссылки на переменные. .NET также поддерживает локальные переменные , которые содержат управляемые ссылки на другие переменные. (Однако обратите внимание, что .NET не поддерживает поля или массивы , которые содержат управляемые ссылки на другие переменные, поскольку это слишком усложняет историю сбора мусора. не преобразуется в объект и поэтому не может использоваться в качестве аргументов типа для универсальных типов или методов.)
Комментатор "RPM1984" по какой-то причине попросил процитировать этот факт. RPM1984 Я рекомендую вам прочитать Раздел 8.2.1.1 «Управляемые указатели и связанные типы» спецификации CLI для получения информации об этой функции .NET.
Вполне возможно создать версию C #, которая поддерживает обе эти функции. Затем вы могли бы делать такие вещи, как
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
, а затем позвоните по номеру
int a = 123;
int b = 456;
ref int c = ref Max(ref a, ref b);
c += 100;
Console.WriteLine(b); // 556!
Я знаю эмпирически, что можно создать версию C #, которая поддерживает эти функции , потому что я сделал это . Опытные программисты, в особенности люди, портирующие неуправляемый код C ++, часто просят нас о дополнительной C ++ -подобной способности делать вещи со ссылками, без необходимости извлекать большую пользу из использования указателей и закрепления памяти повсюду. Используя управляемые ссылки, вы получаете эти преимущества, не оплачивая затраты на сборку мусора.
Мы рассмотрели эту функцию и фактически реализовали ее достаточно, чтобы показать другим внутренним командам, чтобы получить их отзывы. Однако в настоящее время, основываясь на нашем исследовании , мы считаем, что эта функция не имеет достаточно широкой привлекательности или убедительных вариантов использования, чтобы превратить ее в реальную поддерживаемую языковую функцию . У нас есть другие более высокие приоритеты и ограниченное количество времени и усилий, поэтому мы не собираемся делать эту функцию в ближайшее время.
Кроме того, для правильной работы потребуются некоторые изменения в CLR. В настоящее время CLR рассматривает методы возврата-возврата как допустимые , но не проверяемые , потому что у нас нет детектора, который обнаруживает эту ситуацию:
ref int M1(ref int x)
{
return ref x;
}
ref int M2()
{
int y = 123;
return ref M1(ref y); // Trouble!
}
int M3()
{
ref int z = ref M2();
return z;
}
M3 возвращает содержимое локальной переменной M2, но время жизни этой переменной закончилось! Можно написать детектор, который определяет использование реф-возвратов, которые явно не нарушают безопасность стека. Что бы мы сделали, это напишем такой детектор, и если бы детектор не смог доказать безопасность стека, то мы бы не допустили использование ref-возвратов в этой части программы. Для этого не так много работы разработчиков, но для команд тестирования очень тяжело убедиться, что у нас действительно есть все случаи. Это просто еще одна вещь, которая увеличивает стоимость функции до такой степени, что прямо сейчас выгоды не перевешивают затраты.
Если вы можете описать мне, почему вы хотите эту функцию, я был бы очень признателен за это . Чем больше у нас информации от реальных клиентов о том, почему они этого хотят, тем больше вероятность, что она когда-нибудь попадет в продукт. Это милая маленькая функция, и я бы хотел как-то донести ее до покупателей, если будет достаточно интереса.
(См. Также связанные вопросы Можно ли вернуть ссылку на переменную в C #? и Можно ли использовать ссылку внутри функции C #, например, C ++? )