6

Angenommen, ich diese einfache Klasse:generieren unveränderliche zyklische Datenstrukturen

public class Pair { 
    public readonly object first; 
    public readonly object second; 

    public Pair(object first, object second) { 
     this.first = first; 
     this.second = second; 
    } 
} 

Es wäre unmöglich, eine zyklische Graph von Paaren zu erzeugen.

Wie würden Sie eine ähnliche Klasse erstellen, die immer noch unveränderbar ist, aber irgendwie zum Generieren von zyklischen Graphen verwendet werden kann?

+0

Es scheint übrigens unmöglich für mich. – configurator

+0

Eine gute Antwort wird sprachspezifisch sein. Sie sollten dies in Ihrer bevorzugten Sprache markieren. –

+2

Lazy Evaluation verwenden und die Zyklen rekursiv definieren – Dario

Antwort

0

Ich glaube nicht, dass dies mit einer streng unveränderlichen Klasse des von Ihnen vorgeschlagenen Typs möglich ist. Das einzige, was mir einfällt, ist das Hinzufügen einer Eigenschaft mit einem Setter, der prüft, ob ein Feld null ist oder nicht, und erlaubt, dass es gesetzt wird, wenn es das ist. Auf diese Weise können Sie das Feld first im ersten Objekt null belassen, und nachdem Sie das letzte Objekt im Zyklus erstellt haben, setzen Sie dieses Feld entsprechend, um die Schleife zu schließen. Sobald es gesetzt ist, ist es nicht länger null und der Setter würde es nicht länger erlauben, dass es geändert wird. Es wäre natürlich immer noch möglich, das Feld durch einen internen Code für die Klasse zu ändern, aber es wäre von außen im wesentlichen unveränderlich.

So etwas wie diese (C#):

public class Pair { 
    private object first; 
    private object second; 

    public Pair(object first, object second) { 
     this.first = first; 
     this.second = second; 
    } 

    public object First { 
     get { return first; } 
     set 
     { 
      if (first == null) 
      { 
       first = value; 
      } 
     } 
    } 

    // and a similar property for second 
} 
+0

Vorsicht vor der Fadensicherheit ... Häufig ist Unveränderbarkeit mit der Fadensicherheit verbunden, aber in diesem Fall macht die offensichtliche Unveränderlichkeit Ihres 'Paar'-Typs es nicht threadsicher! Angenommen, Sie haben 'var a = new Pair (1, null); var b = neues Paar (null, 2); b.first = a; a.second = b', und veröffentlichen Sie dann das Objekt, auf das mit 'a' verwiesen wird (damit andere Threads es sehen können). Ohne die richtige Synchronisation sehen andere Threads das "a.second == null"! –

3

Es Myriaden von Möglichkeiten sind Graphenstrukturen darzustellen. Ein solcher Weg ist mit einer Matrix. Jede Zeile und Spalte wird durch den Scheitelpunkt indiziert, und jede Zelle in der Matrix repräsentiert eine gerichtete (möglicherweise gewichtete) Kante. Eine einfache, zyklische Graph, mit 0'en, da keine Verbindungskante und 1 mit einer Verbindungskante wie so wäre:

| 0 1 | 
| 1 0 | 

Wie bei vielen unveränderlichen Strukturen, wie du dich konstruieren ist durch neue Strukturen der Rückkehr auf der Grundlage des gewünschte Beziehung gegebener Matrizen. Wenn wir zum Beispiel das obige Diagramm verwenden und eine Kante auf dem ersten Eckpunkt auf sich selbst zurückführen möchten, ist die Matrix, die das darstellt, gerade.

| 1 0 | 
| 0 0 | 

und um das mit der anderen Matrix zu kombinieren, fügen wir sie einfach zusammen.

| 0 1 | + | 1 0 | == | 1 1 | 
| 1 0 |  | 0 0 |  | 1 0 | 

Natürlich gibt es viele Möglichkeiten Matrizen darzustellen, mit unterschiedlichen Vor- und Nachteile für die Geschwindigkeit, Raum und bestimmte andere Operationen, aber das ist eine andere Frage.

0

Ich würde einen funktionalen Ansatz nehmen, eine Fortsetzung in den Ctor übergeben. Alternativ könnte es stattdessen eine Folge ähnlicher Elemente enthalten (denke IEnumerable als Argument).