Frage

Nach [MSDN: Array Nutzungsrichtlinien] ( http://msdn.microsoft.com/en-us/library/k2604h5s (VS.71) .aspx) :

Array Valued Properties

  

Sie sollten Sammlungen verwenden, um Code Ineffizienzen zu vermeiden. Im folgenden Codebeispiel erzeugt jeder Aufruf der myObj Eigenschaft eine Kopie des Arrays. Als Ergebnis 2n + 1 Kopien des Arrays werden in der folgenden Schleife erstellt werden.

[Visual Basic]

Dim i As Integer
For i = 0 To obj.myObj.Count - 1
   DoSomething(obj.myObj(i))
Next i

[C#]
for (int i = 0; i < obj.myObj.Count; i++)
      DoSomething(obj.myObj[i]);

Anders als die Änderung von myObj [] zu ICollection myObj, was sonst würden Sie empfehlen? Nur erkannte, dass meine aktuellen App-Speicher undicht ist: (

Danke;

EDIT: Würde zwingt C # Referenzen w / ref zu passieren (Sicherheit beiseite) verbessert die Leistung und / oder Speichernutzung

?
War es hilfreich?

Lösung

Nein, es ist nicht undichte Speicher - es ist nur macht die Garbage Collector härter arbeiten, als es könnte. Eigentlich ist der MSDN-Artikel etwas irreführend ist: wenn die Eigenschaft eine neue Sammlung erstellt , jedes Mal heißt es, wäre es genauso schlecht (Speicher weist) wie mit einem Array. Vielleicht noch schlimmer, wegen der üblichen Überdimensionierung der meisten Sammlung Implementierungen.

Wenn Sie wissen, eine Methode / Eigenschaft funktioniert, können Sie immer die Anzahl der Anrufe minimieren:

var arr = obj.myObj; // var since I don't know the type!
for (int i = 0; i < arr.Length; i++) {
  DoSomething(arr[i]);
}

oder noch einfacher, Verwendung foreach:

foreach(var value in obj.myObj) {
  DoSomething(value);
}

Beide Ansätze nur die Eigenschaft nennen einmal. Die zweite ist IMO klarer.

Andere Gedanken; nennen Sie es eine Methode! das heißt obj.SomeMethod() -. Dies setzt Erwartung, dass es funktioniert, und vermeidet das unerwünschte obj.Foo != obj.Foo (was der Fall für Arrays wäre)

Schließlich hat Eric Lippert einen guten

Andere Tipps

Nur als Hinweis für diejenigen, die nicht das in Readonlycollection einige der Antworten erwähnt verwenden haben:

[C#]

class XY
{
  private X[] array;

  public ReadOnlyCollection<X> myObj
  {
    get
    {
      return Array.AsReadOnly(array);
    }
  }
}

Hope Dies könnte helfen.

Immer wenn ich Eigenschaften haben, die teuer sind (wie eine Sammlung auf Abruf neu zu erstellen) Ich entweder Dokument die Eigenschaft, die besagt, dass jeder Anruf eine Kosten mit sich bringt, oder ich cachen den Wert als privates Feld. Property Getter, die teuer sind, sollten als Methoden geschrieben werden. Im Allgemeinen versuche ich, Sammlungen wie IEnumerable aussetzen, anstatt Arrays und zwingt den Verbraucher foreach zu verwenden (oder einen Enumerator).

Es wird keine Kopien des Arrays machen, wenn Sie es so behelfen. Allerdings nur auf eine Anordnung die Referenz vorbei privat von einem Objekt im Besitz hat einige unangenehmen Nebenwirkungen. Wer erhält die Referenz grundsätzlich frei ist zu tun, was er mit dem Array mag, einschließlich der Inhalte in einer Weise zu verändern, die nicht von seinem Besitzer kontrolliert werden kann.

Eine Möglichkeit zur Verhinderung unbefugte Einmischung mit dem Array ist eine Kopie des Inhalts zurückzukehren. Weitere (etwas besser) ist eine schreibgeschützte Sammlung zurück.

Noch bevor alle diese Dinge tun, die Sie sich stellen sollten, wenn Sie dabei sind, zu viele Informationen zu verschenken. In einigen Fällen (eigentlich recht häufig) ist es sogar besser, das Array privat zu halten und stattdessen Methoden lassen bereitzustellen, die auf dem Objekt arbeiten, es zu besitzen.

myobj nicht neues Element erstellen, wenn Sie explizit erstellen. so zu einem besseren Speichernutzung zu machen empfehle ich Privatsammlung zu verwenden (List oder vorhanden) und belichten Indexer, die den angegebenen Wert aus der Privatsammlung zurückkehren

scroll top