Prinzip:Kontrollieren Sie Änderungen an Daten so weit wie möglich. Wenn Sie vorhersagen können, dass bestimmte Daten nicht geändert werden oder nicht geändert werden sollten, kontrollieren Sie dies, und erwarten Sie nicht, dass Aufrufer, die diese Daten verwenden, ihren Wert nicht ändern.

Wenn ein Parameter während der Verwendung versehentlich geändert wird, kann dies unvorhersehbare Ergebnisse mit sich bringen, und solche Fehler sind schwer zu erkennen. Daher müssen wir beim Entwerfen von Methodenparametern die möglichen Folgen der Übergabe von Parametern vom Referenztyp oder der Übergabe von Parametern vom Referenztyp per Referenz vollständig berücksichtigen.

Wenn Daten während der Übergabe nicht geändert werden dürfen, sollten ihre Werte (Felder oder Eigenschaften) beim Erstellen des Objekts unveränderlich gemacht werden.


I. Kontrolle einfacher Parameter

1. Übergabe von Werttypparametern

In diesem Fall wird eine Kopie des Parameters übergeben, daher wird der ursprüngliche Wert nicht beeinflusst, sodass keine Kontrolle erforderlich ist.

2. Übergeben von Referenztyp-Parametern

a. Datenstrukturen aus Werttypen

Felder müssen als schreibgeschützt festgelegt werden, und Eigenschaften sollten nur Getter haben. Eine Zuweisung kann nur über Konstruktoren erfolgen.

b. Datenstrukturen, die Referenztyp-Felder enthalten

Diese Situation ist rekursiv. Während sichergestellt wird, dass Felder schreibgeschützt sind und Eigenschaften nur Getter haben, müssen auch die von Referenztyp-Feldern verwendeten Typen dieselben Anforderungen erfüllen.

public class SuperClass
{
    private readonly int  _no;
    private readonly SubClass _tag;

    public int NO
    {
        get{ return _no;}
    }

    public SubClass Tag
    {
        get{ retirn _tag;}
    }

    public SuperClass(int no,SubClass tag)
    {
        _no=no;
        _tag=tag;   
    }
}


public class SubClass
{
    private readonly int _field;

    public int Field
    {
        get{ return _field;}
    }

    public SubClass(int field)
    {
        _field=field;
    }
}

II. Kontrolle über die Übergabe komplexer Referenztyp-Parameter

Mit „komplex“ ist gemeint, dass der Parameter ein Array- oder Sammlungstyp ist oder dass der Parameter Daten dieser Typen enthält. In diesem Fall können die oben genannten Methoden nicht garantieren, dass die Parameterdaten nicht geändert werden, denn selbst wenn das Objekt schreibgeschützt ist, können die Array- oder Sammlungsfelder (oder -eigenschaften) im Objekt weiterhin geändert werden.

1. Sammlungsparameter (Gleiches gilt für Referenzparameter, die Sammlungsfelder enthalten)

Für Versionen vor .NET 4.5 können Sie Schnittstellen verwenden, die keine Methoden zum Ändern von Sammlungselementen enthalten, um konkrete Sammlungstypen zu ersetzen. Verwenden Sie beispielsweise IEnumerableSchnittstelle anstelle von ListIn .NET 4.5 können Sie direkt die IReadOnlyCollection-Schnittstelle oder Sammlungstypen verwenden, die diese Schnittstelle implementieren.

2. Array-Parameter

Es gibt keine gute Möglichkeit, Array-Parameter vor Änderung zu schützen, daher sollte man Array-Typen als Methodenparameter möglichst vermeiden, außer wenn optionale Parameter benötigt werden.


III. Um das Obige zu verstehen, müssen Sie die Unterschiede zwischen den folgenden Konzepten klar unterscheiden

  • 1. Der Unterschied zwischen Werttypen und Referenztypen
  • 2. Der Unterschied zwischen Übergabe nach Wert und Übergabe nach Referenz (ref und out)
  • 3. Der Unterschied zwischen Übergabe von Parametern vom Referenztyp und Übergabe von Parametern vom Referenztyp per Referenz (ref und out) [Dieser Punkt ist am verwirrendsten]

Der Unterschied besteht darin, dass, wenn während der Verwendung des Parameters ein neues Objekt für die Referenz erstellt wird, Ersteres den ursprünglichen Wert nicht beeinflusst, während Letzteres den ursprünglichen Wert beeinflusst. Beispiel:

void FunA(MyClass a)
{
     a=new MyClass("A");
}

void FunB(ref MyClass a)
{
    a=new MyClass("B");
}

 

void Test()
{
    MyClass a=new MyClass("A"); 
    FunA(a);
    Print(a);              //a还是原始的对象 TEST
    FunB(ref a);
    Print(a);               //a变为新对象   B
}

Merken Sie sich ein Prinzip:Werttypen übergeben eine Kopie des Werts, Referenztypen übergeben eine Objektreferenz. Daher wirken sich Änderungen an Wertparametern nicht auf den ursprünglichen Wert aus, während Änderungen an Referenztypen den ursprünglichen Wert beeinflussen; das Konstruieren eines per Wert übergebenen Parameters beeinflusst den ursprünglichen Wert nicht, während die Übergabe per Referenz (ref und out) den ursprünglichen Wert beeinflusst.

Originaladresse: https://www.cnblogs.com/from1991/p/5335585.html