2010-08-13 26 views
7

Ho una lista che è dichiarata di seguito, all'inizio ho impostato di default gli elementi della lista su {-1, -}. Si prega di notare che tutto il programma le dimensioni dell'elenco è fissata a 2..NET Approccio migliore elenco

List<int> list = new List<int>(new int[] {-1, -1}); 

La mia domanda è per quanto riguarda, quale sarebbe l'approccio migliore se ho bisogno di sovrascrivere i due valori nella lista.

int x = GetXValue(); 
int y = GetYValue(); 

Approccio 1:

list = new List<int>(new int[] {x, y}); 

Approccio 2:

list[0] = x; 
list[1] = y; 

quello che sarebbe un approccio migliore? Con il secondo approccio, anche se sono sicuro che inizialmente ci sono 2 valori impostati, posso correre il rischio dell'eccezione Argument index out of range. Ma il primo approccio potrebbe mangiare più memoria (correggimi se sbaglio!) Poiché sto creando una nuova lista ogni volta.

Esiste una soluzione più semplice, e/o meglio

risposta

12

O c'è una soluzione più semplice e migliore ?

Sì. Dal momento che la lista ha una dimensione fissa, utilizzare un oggetto reale come ad esempio System.Drawing.Point:

Point p = new Point(1, -1); 
p = new Point(5, 10); 
Console.WriteLine("X = {0}, Y = {1}", p.X, p.Y); 
+0

Bel call on point. Stavo pensando che l'IDictionary avrebbe ottenuto lo stesso risultato. –

+2

+1: l'utilizzo di un elenco (di dimensioni dinamiche) crea ambiguità per il tipo, in cui i commenti DEVONO essere utilizzati per indicare l'utilizzo previsto. Se non si desidera un tipo CLR, si richiede una struttura o un oggetto personalizzato. –

+0

+1 - Idea intelligente! –

0

Forse non capisco lo scenario, ma credo che una soluzione migliore sarebbe un semplice array ??

int[] list = new int[] { -1, 1 }; 
+0

Personalmente ritengo che gli array siano cattivi. Il mio obiettivo era cercare di evitarli. –

0

mi sento di raccomandare di utilizzare una matrice, il che significa che la raccolta rimane a una dimensione fissa e il secondo metodo per accedervi. Quindi:

int[] array = new[] { -1, -1 }; 

e poi a cambiarla:

array[0] = x; 
array[1] = y; 

Dato che la matrice non cambia dimensioni, e 2 i valori sono assegnati ad esso, non sarà possibile ottenere un IndexOutOfRangeException. Di solito non userei il primo metodo per cambiare il contenuto di una collezione - in generale è meglio cambiare un oggetto esistente piuttosto che crearne uno nuovo.


Proprio come un a parte, è possibile scrivere un initialiser per un List<T> come:

new List<int> {-1, -1}; 
1

Questo appare come vuole essere incapsulato, che eliminerebbe la complessità al luogo di utilizzo.

L'incapsulamento dovrebbe fornire tutti i comportamenti, inclusi a partire da -1, -1 e l'impostazione sia X e Y allo stesso tempo. Si potrebbe fare qualcosa di simile:

public class ItemSet 
{ 
    public ItemSet() 
    { 
     this.X = -1; 
     this.Y = -1; 
    } 

    public int X { get; private set; } 

    public int Y { get; private set; } 

    public void SetItems(int x, int y) 
    { 
     this.X = x; 
     this.Y = y; 
    } 
} 
1

perché non una classe personalizzata, qualcosa di simile, soprattutto perché si tratta di una dimensione fissa.

class MyClass { 
    public MyClass(int x, int y) { 
    } 
    public int X { get; set; } 
    public int Y { get; set; } 

    public int[] ToArray() { 
     return new[] { X, Y }; 
    } 
    public List<int> ToList() { 
     return ToArray().ToList(); 
    } 
} 
+0

Le lezioni personalizzate sono buone. Ma penso che sarebbe solo un codice extra che deve essere mantenuto. Grazie comunque per l'idea. Mi piace usare i getter ei setter, rende la vita gestibile :) –

1

Struct potrebbe funzionare anche

public struct Point 
{ 
    public int X { get; set; } 
    public int Y { get; set; } 

    public Point(int x, int y):this() 
    { 
     this.X = x; 
     this.Y = y; 
    } 
} 

Point p = new Point(-1, -1); 
// ... 
p.X = newX; 
p.Y = newY; 
1

Approccio 2 sarebbe meglio perché allocazione approccio dell'1 cause memoria inutili (creare una nuova lista, e matrice, ecc)

Tuttavia, il fatto che la tua lista ha sempre solo 2 elementi in esso mi fa pensare che una lista sia la classe sbagliata da usare nel tuo scenario.

Problemi correlati