Diese Frage war das Thema meines Blogs am 23. Juni 2011 . Danke für die tolle Frage!
Das C # -Team erwägt dies für C # 7. Weitere Informationen finden Sie unter https://github.com/dotnet/roslyn/issues/5233 .
UPDATE: Die Funktion hat es in C # 7 geschafft!
Du hast Recht; .NET unterstützt Methoden, die verwaltete Verweise auf Variablen zurückgeben. .NET unterstützt auch lokale Variablen , die verwaltete Verweise auf andere Variablen enthalten. (Beachten Sie jedoch, dass .NET keine Felder oder Arrays unterstützt , die verwaltete Verweise auf andere Variablen enthalten, da dies die Garbage Collection-Story übermäßig kompliziert. Auch die Typen "verwalteter Verweis auf Variablen" sind nicht in Objekte konvertiert werden und werden daher möglicherweise nicht als verwendet Typargumente für generische Typen oder Methoden.)
Der Kommentator "RPM1984" bat aus irgendeinem Grund um ein Zitat für diese Tatsache. RPM1984 Ich empfehle Ihnen, die CLI-Spezifikation Partition I Abschnitt 8.2.1.1, "Verwaltete Zeiger und verwandte Typen" zu lesen, um Informationen zu dieser Funktion von .NET zu erhalten.
Es ist durchaus möglich, eine Version von C # zu erstellen, die beide Funktionen unterstützt. Sie könnten dann Dinge wie tun
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
und dann nenne es mit
int a = 123;
int b = 456;
ref int c = ref Max(ref a, ref b);
c += 100;
Console.WriteLine(b); // 556!
Ich weiß empirisch, dass es möglich ist, eine Version von C # zu erstellen, die diese Funktionen unterstützt weil ich dies getan habe . Fortgeschrittene Programmierer, insbesondere Leute, die nicht verwalteten C ++ - Code portieren, fragen uns oft nach mehr C ++ - ähnlichen Möglichkeiten, Dinge mit Referenzen zu tun, ohne den großen Hammer herausholen zu müssen, Zeiger zu verwenden und Speicher überall festzunageln. Durch die Verwendung verwalteter Referenzen erhalten Sie diese Vorteile, ohne die Kosten für die Leistungssteigerung Ihrer Speicherbereinigung zu bezahlen.
Wir haben diese Funktion in Betracht gezogen und tatsächlich genug implementiert, um sie anderen internen Teams zu zeigen, um deren Feedback zu erhalten. Aufgrund unserer Untersuchungen glauben wir jedoch, dass das Feature derzeit nicht breit genug ansprechend oder überzeugend ist, um es zu einem wirklich unterstützten Sprachfeature zu machen . Wir haben andere höhere Prioritäten und einen begrenzten Zeit- und Arbeitsaufwand zur Verfügung, daher werden wir diese Funktion in Kürze nicht mehr ausführen.
Um es richtig zu machen, müssten einige Änderungen an der CLR vorgenommen werden. Derzeit behandelt die CLR Rückgabemethoden als legal, aber nicht überprüfbar, da wir keinen Detektor haben, der diese Situation erkennt:
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 gibt den Inhalt der lokalen Variablen von M2 zurück, aber die Lebensdauer dieser Variablen ist abgelaufen! Es ist möglich, einen Detektor zu schreiben, der die Verwendung von Ref-Returns bestimmt, die die Stapelsicherheit eindeutig nicht verletzen. Wir würden einen solchen Detektor schreiben, und wenn der Detektor die Stapelsicherheit nicht nachweisen könnte, würden wir die Verwendung von Ref-Rückgaben in diesem Teil des Programms nicht zulassen. Es ist keine große Menge an Entwicklungsarbeit, aber es ist eine große Belastung für die Testteams, sicherzustellen, dass wir wirklich alle Fälle haben. Es ist nur eine andere Sache, die die Kosten der Funktion so weit erhöht, dass die Vorteile derzeit die Kosten nicht überwiegen.
Wenn Sie mir beschreiben können, warum Sie diese Funktion wünschen, würde ich das sehr begrüßen . Je mehr Informationen wir von echten Kunden darüber haben, warum sie es wollen, desto wahrscheinlicher wird es eines Tages in das Produkt gelangen. Es ist ein süßes kleines Feature und ich würde es gerne irgendwie zu Kunden bringen können, wenn es genügend Interesse gibt.
(Siehe auch verwandte Fragen. Ist es möglich, eine Referenz auf eine Variable in C # zurückzugeben? Und kann ich eine Referenz in einer C # -Funktion wie C ++ verwenden? )