2010-08-06 3 views

Antwort

6

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)

+1

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?) –

+1

@Craig Johnston: Ich empfehle Ihnen beim Sehen Durch den Nebel der Antworten und Debatten wird Ihre scheinbar geradlinige Frage provoziert! –

+0

+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. –

3

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(); 
    } 
} 
4

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.

+2

+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. –

+2

@Binary: Haben Sie Beweise/Referenzen für diesen Anspruch? – CJ7

+0

@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 –

0

Sie können den out Parameter mit Feldern (oder Einheimischen wie bereits erwähnt) verwenden.

4

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

+1, interessante Analyse. – Heinzi