2009-05-27 19 views
5

Ho bisogno di scrivere una funzione che richiederà un numero variabile di argomenti. Leggo un po 'di params [], ma non penso che funzionerà nel mio caso. La mia funzione deve prendere un numero variabile di ints e quindi un valore bool corrispondente per ognuno di essi. Devo scorrere tutte queste combinazioni e inserirle in un database. Sto solo cercando qualcuno che mi indichi la giusta direzione. Grazie.Passaggio di numero variabile di argomenti

risposta

16

Suggerirei di costruire una struttura e quindi passare quelli in come parametri. Nel mio esempio, lo struct rappresenta un punteggio di qualche tipo:

public struct RaceScore 
{ 
    public bool FinishedRace; 
    public int Points; 
} 

La tua firma metodo sarebbe allora:

public void SaveScores(params RaceScore[] scores) 

Ecco un esempio di SaveScores chiamata:

RaceScore score = new RaceScore() { FinishedRace = true, Points = 20 }; 
RaceScore score2 = new RaceScore() { FinishedRace = false, Points = 15 }; 
SaveScores(score, score2); 
+2

Va notato che una struttura è davvero appropriata solo per un paio di variabili. Una classe è più adatta per qualcosa di più. –

+0

Solo per curiosità, perché una struttura sarebbe inappropriata per più di alcune variabili? –

+1

In parte a causa della semantica delle strutture pass-by-value: ogni volta che ne passi uno in un metodo, viene creata una copia, che è più costosa del passaggio di un riferimento (che è ciò che accadrebbe se passassi invece un tipo di riferimento) . – Ant

5

Esatto, non funzionerà come descritto. Quello che potresti fare è usare una struct per unire il valore int e bool. Parametri di struct stanno lavorando:

public struct IntBoolStruct { 
    public bool BoolValue; 
    public int IntValue; 
} 

public void YourMethod(params IntBoolStruct[] values) {} 

EDIT: A seconda di ciò che si vuole fare, un int nullable potrebbe aiutare, anche.

public void YourMethod(params int?[] values) {} 
+0

+1 per il suggerimento nullable. Ottimo punto: potrebbe essere sufficiente, a seconda dello scopo del bool. –

11

Puoi fai questo con i parametri, ma i parametri devono essere una classe o una struttura che contenga il tuo int + il tuo bool. KeyValuePair<TKey,TValue> nelle librerie della classe base funzionerebbe, se non si desidera scrivere la propria classe o struttura.

Se hai intenzione di scorrere su di essi, tuttavia, ti consiglio di utilizzare IEnumerable<T> invece, poiché è molto più semplice da usare.

Ad esempio:

public void SaveValues(IEnumerable<KeyValuePair<int,bool>> values) 
{ 
    foreach(var pair in values) 
    { 
     int intVal = pair.Key; 
     bool boolVal = pair.Value; 
     // Do something here... 
    } 
} 

La stessa cosa avrebbe lavorato con params, vale a dire:

public void SaveValues(params KeyValuePair<int,bool>[] values) 

Questo, però, ti costringe a fare un array. L'utilizzo di IEnumerable<T> funzionerà con un array, ma funzionerà anche con elenchi di valori, risultati di query LINQ, ecc. Ciò rende più facile chiamare questa funzione in molti casi.

+1

+1. Soluzione migliore della risposta del mio dizionario, non avrei dovuto supporre che gli interi fossero ID. – Brandon

+1

Sembra che sarebbe perfetto, ma non penso che sia disponibile in 1.1, che è quello che mi è limitato con questo progetto. Avrei dovuto saperlo. –

0

E un'altra risposta: è possibile farlo con un semplice array di oggetti e parametri.

class paramstest { 
     private void _passALot(params Object[] values) { 
      System.Console.WriteLine(" [foreach]"); 

      foreach (object o in values) { 
       System.Console.Write(o.ToString() + ", "); 
      } 

      System.Console.WriteLine(System.Environment.NewLine + " [for]"); 

      for (int i = 0; i < values.Length; i += 2) { 
       int? testval = values[i] as Int32?; 
       bool? testbool = values[i + 1] as Boolean?; 

       System.Console.WriteLine(String.Format("Int: {0}, Bool: {1}", testval, testbool)); 
      } 
     } 

     public void test() { 
      _passALot(1, true, 2, false, 3, true, "q", false); 
     } 
    } 

dando

 
[foreach] 
1, True, 2, False, 3, True, q, False, 
[for] 
Int: 1, Bool: True 
Int: 2, Bool: False 
Int: 3, Bool: True 
Int: , Bool: False 

passando un dizionario o un elenco con una struct appropriata sarebbe meglio però :)

Problemi correlati