Przeczytałem, że .NET obsługuje zwracanie odwołań, ale C # tego nie robi. Czy jest jakiś szczególny powód? Dlaczego nie mogę zrobić czegoś takiego:
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
c#
.net
reference
return-type
Tom Sarduy
źródło
źródło
return ref x
C# 7
:)Odpowiedzi:
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
a następnie zadzwoń za pomocą
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ę:
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 ++? )
źródło
y
przy życiu po powrocie zM2
? Spodziewałbym się, że ta funkcja będzie działać jak lambdy przechwytujące lokalne. A może jest to zachowanie, które zaproponowałeś, ponieważ jest to sposób, w jaki środowisko CLR obsługuje ten scenariusz?Mówisz o metodach, które zwracają odniesienie do typu wartości. Jedyny wbudowany przykład w C #, o którym wiem, to metoda dostępu do tablicy typu wartości:
a teraz utwórz tablicę o tej strukturze:
W tym przypadku indeksator
points[0]
tablicy zwraca odwołanie do struktury. Niemożliwe jest napisanie własnego indeksatora (na przykład dla kolekcji niestandardowej), który ma takie samo zachowanie „zwraca odwołanie”.Nie zaprojektowałem języka C #, więc nie znam wszystkich powodów, dla których go nie obsługuję, ale myślę, że krótka odpowiedź może brzmieć: bez niego możemy sobie dobrze radzić.
źródło
Zawsze możesz zrobić coś takiego:
źródło
C # 7.0 obsługuje zwracanie odwołań. Zobacz moją odpowiedź tutaj .
źródło