To pytanie było tematem mojego bloga 23 czerwca 2011 roku . Dzięki za świetne pytanie!
Zespół C # rozważa to dla języka C # 7. Zobacz https://github.com/dotnet/roslyn/issues/5233, aby uzyskać szczegółowe informacje.
AKTUALIZACJA: Funkcja została wprowadzona do C # 7!
Masz rację; NET obsługuje metody, które zwracają zarządzane odwołania do zmiennych. NET obsługuje również zmienne lokalne, które zawierają zarządzane odwołania do innych zmiennych. (Należy jednak pamiętać, że .NET nie obsługuje pól ani tablic, które zawierają zarządzane odwołania do innych zmiennych, ponieważ to nadmiernie komplikuje historię czyszczenia pamięci. Również typy „zarządzanych odwołań do zmiennych” nie są konwertowane na obiekt i dlatego nie mogą być używane jako wpisz argumenty na typy ogólne lub metody).
Komentator „RPM1984” z jakiegoś powodu poprosił o przytoczenie tego faktu. RPM1984 Zachęcam do przeczytania specyfikacji CLI Partition I Section 8.2.1.1, "Managed pointers and related types", aby uzyskać informacje na temat tej funkcji .NET.
Całkowicie możliwe jest utworzenie wersji C #, która obsługuje obie te funkcje. Możesz wtedy robić takie rzeczy jak
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
a następnie zadzwoń za pomocą
int a = 123;
int b = 456;
ref int c = ref Max(ref a, ref b);
c += 100;
Console.WriteLine(b); // 556!
Wiem empirycznie, że jest możliwe zbudowanie wersji C #, która obsługuje te funkcje, ponieważ tak zrobiłem . Zaawansowani programiści, szczególnie osoby przenoszące niezarządzany kod C ++, często proszą nas o więcej możliwości, takich jak C ++, robienia rzeczy z referencjami bez konieczności wyciągania wielkiego młota związanego z faktycznym używaniem wskaźników i przypinaniem pamięci w dowolnym miejscu. Korzystając z referencji zarządzanych, uzyskujesz te korzyści bez ponoszenia kosztów związanych z pogorszeniem wydajności usuwania elementów bezużytecznych.
Rozważaliśmy tę funkcję i faktycznie wdrożyliśmy ją na tyle, aby pokazać ją innym zespołom wewnętrznym w celu uzyskania ich opinii. Jednak w tej chwili, na podstawie naszych badań, uważamy, że ta funkcja nie ma wystarczająco szerokiego odwołania lub przekonujących przypadków użycia, aby stała się prawdziwą obsługiwaną funkcją językową . Mamy inne, wyższe priorytety oraz ograniczoną ilość czasu i wysiłku, więc nie zamierzamy robić tej funkcji w najbliższym czasie.
Również wykonanie tego poprawnie wymagałoby pewnych zmian w CLR. W tej chwili CLR traktuje metody powrotu jako legalne, ale nieweryfikowalne, ponieważ nie mamy detektora, który wykrywa tę sytuację:
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 zwraca zawartość zmiennej lokalnej M2, ale czas życia tej zmiennej dobiegł końca! Możliwe jest napisanie detektora, który określa użycie zwrotów ref, które wyraźnie nie naruszają bezpieczeństwa stosu. To co byśmy zrobili, to napisanie takiego detektora, a gdyby detektor nie potrafił udowodnić bezpieczeństwa stosu, to nie pozwolilibyśmy na użycie zwrotów ref w tej części programu. Nie jest to wielka praca deweloperów, ale jest dużym obciążeniem dla zespołów testujących, aby upewnić się, że naprawdę mamy wszystkie przypadki. To tylko kolejna rzecz, która podnosi koszt funkcji do tego stopnia, że w tej chwili korzyści nie przeważają nad kosztami.
Jeśli możesz mi opisać, dlaczego potrzebujesz tej funkcji, byłbym naprawdę wdzięczny . Im więcej mamy informacji od prawdziwych klientów o tym, dlaczego tego chcą, tym większe jest prawdopodobieństwo, że kiedyś trafi do produktu. To urocza mała funkcja i chciałbym móc ją w jakiś sposób przekazać klientom, jeśli jest wystarczające zainteresowanie.
(Patrz również pytania związane jest to możliwe do zwróci referencję do zmiennej w C #? I Czy mogę użyć odwołania wewnątrz funkcji C # jak C ++? )