C#: Können 'out' Parameter in Funktionen Objekteigenschaften/Variablen sein?C#: Können 'out' Parameter in Funktionen Objekteigenschaften/Variablen sein?
zB:
kann ich eine Funktion aufrufen wie folgt:
someFunction(x, y, out myObject.MyProperty1)
C#: Können 'out' Parameter in Funktionen Objekteigenschaften/Variablen sein?C#: Können 'out' Parameter in Funktionen Objekteigenschaften/Variablen sein?
zB:
kann ich eine Funktion aufrufen wie folgt:
someFunction(x, y, out myObject.MyProperty1)
Eigenschaften sind [ein Paar bekommen und setzen] Methoden mit einer netten Syntax für sie aufgerufen wird, dass sie wie Felder aussehen lässt.
Out-Parameter können Referenzen auf Felder sein oder auf der Grundlage ‚Felder‘ Stapel (d.h. einheimische).
Die Überbrückung dieser Lücke im Allgemeinen adressiert wird nicht von Sprachen (und auf jeden Fall nicht direkt durch die CLR und IL-Modell). (+1 auf @Heinzi für die VB Tricks Referenzen)
Eine Begründung für die -1 würde geschätzt werden (abgesehen von der Tatsache, @Mark Byers 'Antwort ist gewachsen, diesen Winkel seit seiner ersten Veröffentlichung zu integrieren?) –
@Craig Johnston: Ich empfehle Ihnen beim Sehen Durch den Nebel der Antworten und Debatten wird Ihre scheinbar geradlinige Frage provoziert! –
+1: Um dies ordnungsgemäß zu erreichen, müssten Sie in der Tat ein Paar Verschlüsse für jede Eigenschaft erfassen. An diesem Punkt wird "ref int i" einen ziemlich komplizierten Code verbergen. . . aber nur wenn eine Eigenschaft übergeben wird. Großer Unterschied zwischen dem Aufheben eines Int-Codes und dem Verwenden von Paaren von Closures. Ps.s. Ich kann Kommentare nicht ohne Kommentare abtun. –
Das Argument für eine Out-Parameter übergeben kann nicht eine Eigenschaft sein. Wenn Sie versuchen, Ihren Code zu kompilieren, erhalten Sie einen Kompilierungsfehler.
Der Grund ist, dass eine Eigenschaft nicht tatsächlich Feld ist (es könnte ein Hintergrundfeld haben, aber es könnte nicht). Es gibt zwei Methoden, die get_Foo
und set_Foo
genannt werden. Eine Erläuterung, warum dies nicht funktioniert, finden Sie unter c# property and ref parameter, why no sugar?.
Beispiel Code, der die Compiler-Fehler gibt:
class Program
{
public int Foo { get; set; }
public void Bar(out int x)
{
x = 5;
}
void Run()
{
Bar(out Foo); // compile error
}
static void Main()
{
new Program().Run();
}
}
Nein, man kann nicht eine Eigenschaft als ref
oder out
Parameter in C# verwenden, da die CLR dies nicht unterstützt. Eine Instanzvariable übergeben sollte gut funktionieren.
Als eine Randnotiz erlaubt VB.NET Eigenschaften zu übergeben und verwendet eine Technik namens "Kopie ByRef", wie in this MSDN blog entry erläutert.
+1: Ich rate dringend von der Weitergabe von Eigenschaften byref in VB.Net, kann überraschende Nebenwirkungen haben, besser wenn - wie C# - es wurde nicht unterstützt. –
@Binary: Haben Sie Beweise/Referenzen für diesen Anspruch? – CJ7
@Craig: Habe unten meine eigene "Antwort" hinzugefügt, mit VB-Code-Beispielen, die zeigen, was ich meine http://stackoverflow.com/questions/3422078/c-can-out-parameters-in-functions-be-object- Eigenschaften-Variablen/3424123 # 3424123 –
Sie können den out
Parameter mit Feldern (oder Einheimischen wie bereits erwähnt) verwenden.
Sie können dies nicht mit C# tun.
Sie können mit VB.Net, aber ich halte das für eine schlechte Idee. Der folgende Code und Ausgang zeigen, wie sie es tut und zeigen, warum ich glaube, es ist eine schlechte Idee, bis zu dem Punkt, wo ich wünsche VB.net auch nicht das diese
Public Class MySimpleClass
Private _privateInt As Integer
Public PublicInt As Integer
Public Property PrivateInt() As Integer
Get
Return _privateInt
End Get
Set(ByVal value As Integer)
_privateInt = value
End Set
End Property
Public Sub MyNotifier()
Console.WriteLine("PublicInt {0} : PrivateInt {1} : Values are not the same", PublicInt, PrivateInt)
End Sub
End Class
Jetzt erlaubten Anruf von einem Unterhaupt, wie so
Sub Main()
Dim sampleClass As New MySimpleClass
IterateAndUpdate(sampleClass.PrivateInt, sampleClass.PublicInt, AddressOf sampleClass.MyNotifier)
Console.WriteLine("Private {0} : Public {0} : values are the same ", sampleClass.PrivateInt, sampleClass.PublicInt)
Console.ReadKey()
End Sub
Sub IterateAndUpdate(ByRef anInt As Integer, ByRef anOtherInt As Integer, ByVal notifier As Action)
For i As Integer = 1 To 9
anInt = i
anOtherInt = i
notifier()
Next
End Sub
Diese gibt
PublicInt 1 : PrivateInt 0 : Values are not the same
PublicInt 2 : PrivateInt 0 : Values are not the same
PublicInt 3 : PrivateInt 0 : Values are not the same
PublicInt 4 : PrivateInt 0 : Values are not the same
PublicInt 5 : PrivateInt 0 : Values are not the same
PublicInt 6 : PrivateInt 0 : Values are not the same
PublicInt 7 : PrivateInt 0 : Values are not the same
PublicInt 8 : PrivateInt 0 : Values are not the same
PublicInt 9 : PrivateInt 0 : Values are not the same
Private 9 : Public 9 : values are the same
Sie können sehen, dass das PublicInt
Mitglied bei ByRef
weitergegeben sofort auf Sample aktualisiert wird, legen Sie die 012.als Eigenschaft freigegeben wird nur aktualisiert, nachdem die IterateAndUpdate
Methode endet.
Deshalb erhalten Sie deutlich unterschiedliches Verhalten von genau die gleichen Aufrufkonvention, und es hängt davon ab, wie Sie das Element übergibt implementiert haben (was auf dem Ruf der Suche nach IterateAndUpdate
haupt nicht klar ist.
Das Potenzial verstecken Fehler oder haben ändern kleine Änderungen erwartete Verhalten ist genug für mich, dieses „Feature“ noch nicht existierte zu wünschen.
meiner Meinung nach nicht richtig funktioniert, daher sollte es entweder
a) Feste, die würde für das Compiler-Team beträchtliche Anstrengungen unternehmen und möglicherweise Unterbrechungsänderungen einführen
oder
b) überhaupt nicht funktionieren
+1, interessante Analyse. – Heinzi
Was sagt der Compiler? – flq
@Frank: Wenn ich das wüsste, warum sollte ich die Frage stellen? – CJ7