6

Supongamos que tengo esta clase simple:estructuras de datos cíclicos inmutables Generación de

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

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

sería imposible para generar un gráfico cíclico de pares.

¿Cómo crearías una clase similar, que todavía es inmutable, pero que se puede usar de alguna manera para generar gráficos cíclicos?

+0

Me parece imposible, por cierto. – configurator

+0

Una buena respuesta va a ser específica del idioma. Debe etiquetar esto en su idioma de preferencia. –

+2

Utilice la evaluación diferida y defina los ciclos recursivamente – Dario

Respuesta

0

No creo que esto sea posible con una clase estrictamente inmutable del tipo que usted propuso. Lo único que se me ocurre es agregar una propiedad con un setter que compruebe si un campo es nulo o no, y permite que se establezca si lo es. De esta forma, puede dejar el campo first en el primer objeto null, y una vez que haya creado el último objeto en el ciclo, establezca ese campo apropiadamente para cerrar el ciclo. Una vez que está configurado, ya no es nulo, y el colocador ya no permitirá que se modifique. Todavía sería posible cambiar el campo por código interno a la clase, por supuesto, pero sería esencialmente inmutable desde el exterior.

Algo como esto (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

Tenga cuidado con la seguridad de las hebras ... A menudo, la inmutabilidad está asociada a la seguridad de las hebras, pero en este caso la aparente inmutabilidad de su tipo 'Pair' no lo hace seguro para nada. Por ejemplo, supongamos que tiene 'var a = new Pair (1, null); var b = new Pair (null, 2); b.first = a; a.second = b', y luego publica el objeto referenciado por 'a' (para que otros hilos puedan verlo). Sin una sincronización adecuada, otros subprocesos podrían ver que 'a.second == null'! –

3

Hay infinidad de maneras de representar las estructuras de gráficos. Una de esas formas es con una matriz. cada fila y columna está indexada por el vértice, y cada celda en la matriz representa un borde dirigido (posiblemente ponderado). A, gráfico cíclico simple, con de 0 como sin borde de conexión y 1 con un borde de conexión sólo sería así:

| 0 1 | 
| 1 0 | 

Al igual que con muchas estructuras inmutables, de la forma que construye es mediante la devolución de las nuevas estructuras basadas en el relación deseada de matrices dadas por ejemplo, si quisiéramos tomar el gráfico anterior y agregar un borde en el primer vértice sobre sí mismo, la matriz que lo representa es justa.

| 1 0 | 
| 0 0 | 

y para combinar eso con la otra matriz, simplemente los agregamos juntos.

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

Por supuesto, hay muchas maneras de representar matrices, con diferentes ventajas y desventajas para la velocidad, el espacio, y algunas otras operaciones, pero eso es una cuestión diferente.

0

Tomaría un enfoque funcional, pasando una continuación al ctor. Alternativamente, podría tomar una secuencia de elementos similares en su lugar (piense en IEnumerable como argumento).

Cuestiones relacionadas