2009-05-27 4 views
5

Je dois écrire une fonction qui prendra un nombre variable d'arguments. J'ai lu un peu au sujet des params [], mais je ne pense pas que ça marchera dans mon cas. Ma fonction doit prendre un nombre variable d'ints et ensuite une valeur de bool correspondant pour chacun d'entre eux. Je dois parcourir chacune de ces combinaisons et les entrer dans une base de données. Je cherche quelqu'un pour me diriger dans la bonne direction. Merci.Passage variable Nombre d'arguments

Répondre

16

Je recommanderais de construire une structure, puis de les transmettre en paramètres. Dans mon exemple, votre struct représente un score quelconque:

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

Votre signature de la méthode serait alors:

public void SaveScores(params RaceScore[] scores) 

Voici un exemple de SaveScores appelant:

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

Il convient de noter qu'une structure n'est vraiment appropriée que pour quelques variables. Une classe convient mieux à n'importe quoi d'autre. –

+0

Juste par curiosité, pourquoi une structure serait-elle inappropriée pour plus de quelques variables? –

+1

En partie à cause de la sémantique pass-by-value des structs: chaque fois que vous passez une méthode, une copie est créée, ce qui revient plus cher que de passer une référence (ce qui arriverait si vous passiez un type de référence) . – Ant

5

C'est vrai - cela ne fonctionnera pas comme décrit. Ce que vous pouvez faire est d'utiliser une structure pour joindre la valeur int et la valeur bool. Params de struct travaillent:

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

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

EDIT: En fonction de ce que vous voulez faire, un int nullable peut vous aider, aussi.

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

+1 pour la suggestion annulable. Bon point - cela pourrait être suffisant, selon le but du booléen. –

11

Vous pouvez faites ceci avec des params, mais les params doivent être une classe ou une structure qui contient votre int + votre bool. KeyValuePair<TKey,TValue> dans les bibliothèques de classes de base fonctionnerait, si vous ne voulez pas écrire votre propre classe ou struct.

Si vous allez les parcourir, cependant, je vous recommande d'utiliser IEnumerable<T> à la place, car il est beaucoup plus simple à utiliser.

Par exemple:

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 même chose travaillerait avec params, à savoir:

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

Ceci, cependant, vous oblige à faire un tableau. L'utilisation de IEnumerable<T> fonctionnera avec un tableau, mais fonctionnera également avec des listes de valeurs, ou des résultats de requête LINQ, etc. Cela facilite la génération de cette fonction dans de nombreux cas.

+1

+1. Meilleure solution que ma réponse de dictionnaire, je n'aurais pas dû supposer que les entiers étaient des identifiants. – Brandon

+1

Cela semble être parfait, mais je ne pense pas qu'il soit disponible en 1.1, ce qui est ce que je suis limité à ce projet. J'aurais dû le noter. –

0

Et une autre réponse: vous pouvez le faire avec un simple objet-tableau et params.

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); 
     } 
    } 

vous donnant

 
[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 

Passer un dictionnaire ou une liste avec une struct appropriée serait mieux si :)

Questions connexes