[C#] Übergeben von Eigenschaften als Verweis in C #


Answers

ohne die Eigenschaft zu duplizieren

void Main()
{
    var client = new Client();
    NullSafeSet("test", s => client.Name = s);
    Debug.Assert(person.Name == "test");

    NullSafeSet("", s => client.Name = s);
    Debug.Assert(person.Name == "test");

    NullSafeSet(null, s => client.Name = s);
    Debug.Assert(person.Name == "test");
}

void NullSafeSet(string value, Action<string> setter)
{
    if (!string.IsNullOrEmpty(value))
    {
        setter(value);
    }
}
Question

Ich versuche folgendes zu tun:

GetString(
    inputString,
    ref Client.WorkPhone)

private void GetString(string inValue, ref string outValue)
{
    if (!string.IsNullOrEmpty(inValue))
    {
        outValue = inValue;
    }
}

Dies gibt mir einen Kompilierungsfehler. Ich denke, es ist ziemlich klar, was ich zu erreichen versuche. Grundsätzlich möchte GetString den Inhalt einer Eingabezeichenfolge in die WorkPhone Eigenschaft des Client WorkPhone .

Ist es möglich, eine Immobilie als Referenz zu übergeben?




Das ist nicht möglich. Du könntest sagen

Client.WorkPhone = GetString(inputString, Client.WorkPhone);

wobei WorkPhone eine schreibbare string und die Definition von GetString geändert wird

private string GetString(string input, string current) { 
    if (!string.IsNullOrEmpty(input)) {
        return input;
    }
    return current;
}

Dies wird die gleiche Semantik haben, für die Sie zu versuchen scheinen.

Dies ist nicht möglich, weil eine Eigenschaft in Wirklichkeit ein Paar verkleideter Methoden ist. Jede Eigenschaft stellt Getter und Setter zur Verfügung, die über eine feldähnliche Syntax zugänglich sind. Wenn Sie versuchen, GetString wie vorgeschlagen aufzurufen, GetString Sie einen Wert und keine Variable. Der Wert, den Sie übergeben, wird vom get_WorkPhone .




Sie könnten versuchen, ein Objekt zu erstellen, das den Eigenschaftswert enthält. Auf diese Weise können Sie das Objekt weitergeben und trotzdem Zugriff auf die darin befindliche Eigenschaft haben.




Wenn Sie die Eigenschaft beide abrufen und festlegen möchten, können Sie dies in C # 7 verwenden:

GetString(
    inputString,
    (() => client.WorkPhone, x => client.WorkPhone = x))

void GetString(string inValue, (Func<string> get, Action<string> set) outValue)
{
    if (!string.IsNullOrEmpty(outValue))
    {
        outValue.set(inValue);
    }
}



Ein weiterer Trick, der noch nicht erwähnt wurde, ist, dass die Klasse, die eine Eigenschaft implementiert (zB Foo vom Typ Bar ) auch einen Delegate- delegate void ActByRef<T1,T2>(ref T1 p1, ref T2 p2); definiert. delegate void ActByRef<T1,T2>(ref T1 p1, ref T2 p2); und implementiere eine Methode ActOnFoo<TX1>(ref Bar it, ActByRef<Bar,TX1> proc, ref TX1 extraParam1) (und möglicherweise Versionen für zwei und drei "zusätzliche Parameter"), die ihre interne Darstellung von Foo an die übergeben wird gelieferte Prozedur als ref Parameter. Dies hat ein paar große Vorteile gegenüber anderen Methoden der Arbeit mit der Immobilie:

  1. Die Eigenschaft wird "vor Ort" aktualisiert; Wenn die Eigenschaft von einem Typ ist, der mit "Interlocked" -Methoden kompatibel ist, oder wenn es sich um eine Struktur mit exponierten Feldern dieser Typen handelt, können die "Interlocked" -Methoden verwendet werden, um atomare Aktualisierungen der Eigenschaft durchzuführen.
  2. Wenn die Eigenschaft eine Struktur mit exponierten Feldern ist, können die Felder der Struktur geändert werden, ohne dass redundante Kopien davon erstellt werden müssen.
  3. Wenn die Methode "ActByRef" einen oder mehrere Ref-Parameter vom Aufrufer an den angegebenen Delegaten weiterleitet, ist es möglicherweise möglich, einen Singleton oder statischen Delegaten zu verwenden, sodass die Erstellung von Schließungen oder Delegaten zur Laufzeit nicht erforderlich ist.
  4. Die Immobilie weiß, wann mit "gearbeitet" wird. Es ist zwar immer notwendig, beim Ausführen einer Sperre Vorsicht walten zu lassen, wenn Sie externen Code ausführen. Wenn Sie jedoch darauf vertrauen können, dass Caller in ihrem Callback keine Aktionen ausführen, die eine andere Sperre erfordern, ist es möglicherweise sinnvoll, die Methode mit a zu schützen sperren, so dass Updates, die nicht mit 'CompareExchange' kompatibel sind, noch quasi-atomar ausgeführt werden können.

Es ist ein ausgezeichnetes Muster, die Dinge zu ref sei ref ; Schade, es wird nicht mehr benutzt.






Links