Це питання було предметом мого блогу 23 червня 2011 року . Дякую за чудове запитання!
Команда C # розглядає це для C # 7. Детальну інформацію див. На https://github.com/dotnet/roslyn/isissue/5233 .
ОНОВЛЕННЯ: Ця функція перетворила його на C # 7!
Ви праві; .NET підтримує методи підтримки, які повертають керовані посилання на змінні. .NET також підтримує локальні змінні, які містять керовані посилання на інші змінні. (Однак зауважте, що .NET не підтримує поля чи масиви, які містять керовані посилання на інші змінні, оскільки це надто ускладнює історію збору сміття. Також типи "керована посилання на змінну" не можуть бути конвертовані в об'єкт , і тому не можуть використовуватися як введіть аргументи на загальні типи чи методи.)
Коментер "RPM1984" чомусь попросив цитувати цей факт. RPM1984 Я рекомендую прочитати специфікацію розділу CLI розділу 8.2.1.1 "Керовані покажчики та пов'язані типи" для отримання інформації про цю особливість .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 ++? )