2010-01-23 4 views
1

J'essaie de créer une méthode Add surchargée en tant qu'extension de la classe OrderedDictionary et j'aimerais ajouter la clé/valeur en fonction de certains prédicats au cari.Aide sur le prédicat <T> délégué

Le code d'appel ressemblerait à ceci:

 

OrderedDictionary dict = new OrderedDictionary(); 

Predicate<int> lessThan5 = i=>; i < 5; 
Predicate<string> lenOf2 = s=> s.length == 2; 

dict.Add("01","Name", lessThan5); 
dict.Add("02","place", lenOf2); 
 

J'ai créé une méthode d'extension comme ceci:


public static class CollectionExtensions 
{ 
    public static void Add(this OrderedDictionary s, string k, string v, Predicate p) 
    { 
     if (p) 
     { 
      d.Add(k, v); 
     } 
    } 
} 

Mais cela ne fonctionne pas parce que je reçois une erreur de compilation de lecture « ne peut pas convertir Prédicat en booléen ".

Est-ce que quelqu'un sait ce que je manque?

Merci pour toute aide. -Keith

+0

La valeur sous-jacente devrait avoir rien à voir avec les paramètres clés ou de valeur. Je souhaite que la fonction de prédicat prenne une valeur. Quelque chose comme ceci: Prédicat showPlaces = new Prédicat (u => u.isAllowed); Prédicat showPeople = nouveau Prédicat (i => i == 5); puis passez le prédicat showPlaces ou showPeople en tant que paramètre à une méthode qui l'évaluera sans passer de paramètre. si (p) d.Ajouter (k, v); – Keith

+0

Comment "un prédicat qui produit une valeur" n'est-il pas simplement une valeur booléenne? Peux-tu expliquer? –

+0

Vous avez raison, Eric. Peut-être que je suis trop penser cela. – Keith

Répondre

3

Le problème est que vous n'évaluez pas votre prédicat pour vérifier si le prédicat est satisfait ou non. Maintenant, il n'est pas clair à partir de votre question si vous voulez que le prédicat teste la clé ou la valeur. Ce qui suit vérifie la clé. Vous devriez également envisager de renvoyer la méthode bool indiquant le succès ou l'échec comme je l'ai fait ici.

static class OrderedDictionaryExtensions { 
    public static bool Add(
     this OrderedDictionary dictionary, 
     string key, 
     string value, 
     Predicate<string> predicate 
    ) { 
     if (dictionary == null) { 
      throw new ArgumentNullException("dictionary"); 
     } 
     if (predicate == null) { 
      throw new ArgumentNullException("predicate"); 
     } 
     if (predicate(key)) { 
      dictionary.Add(key, value); 
      return true; 
     } 
     return false; 
    } 
} 

Utilisation;

// dictionary is OrderedDictionary 
dictionary.Add("key", "value", s => s.Length < 5); 

Vous pouvez réellement généraliser ce un peu car OrderedDictionary n'est pas fortement typé.

static class OrderedDictionaryExtensions { 
    public static bool Add<TKey, TValue>(
     this OrderedDictionary dictionary, 
     TKey key, 
     TValue value, 
     Predicate<TKey> predicate 
    ) { 
     if (dictionary == null) { 
      throw new ArgumentNullException("dictionary"); 
     } 
     if (predicate == null) { 
      throw new ArgumentNullException("predicate"); 
     } 
     if (predicate(key)) { 
      dictionary.Add(key, value); 
      return true; 
     } 
     return false; 
    } 
} 

Utilisation:

// dictionary is OrderedDictionary 
dictionary.Add(17, "Hello, world!", i => i % 2 != 0); 
+0

+1 De bons exemples pourraient être améliorés avec des instructions directes de ce qui ne va pas avec le code de l'OP: 'if' prend bool, alors ne lui passez rien d'autre. Un prédicat doit avoir un argument de type. Un délégué doit être explicitement appelé (et passé tous les arguments requis) pour l'exécuter - comme vous le dites, sommes-nous supposés tester la clé ou la valeur? Et si nous ne pouvons pas le dire, comment pourrait le compilateur? –

+0

Merci, Jason. Je suis nouveau au concept de programmation fonctionnelle alors pardonnez-moi si je ne suis pas clair. La valeur de prédicat ne doit rien avoir à voir avec les paramètres de clé ou de valeur. Je veux que la fonction de prédicat corrige une valeur. Je veux faire quelque chose comme ceci: Prédicat showPlaces = new Prédicat (u => u.isAllowed); Preicate showPeople = nouveau prédicat (i => i == 5); puis passez le prédicat showPlaces ou showPeople en tant que paramètre à une méthode qui l'évaluera sans passer de paramètre. ... si (p) d.Ajouter (k, v); – Keith

+0

@unknown (google): Un prédicat est une fonction mappant un ensemble à '{true, false}'. Les prédicats n'ont pas de valeur de vérité; vous obtenez des valeurs de vérité en les évaluant chez un membre de leur domaine. Ainsi, quand vous dites 'Prédicat p = nouveau Prédicat (i => i == 5)' vous devez noter que 'p' n'a pas de valeur de vérité. Si vous voulez une valeur de vérité de 'p', vous devez l'évaluer à un certain' int'. – jason

Questions connexes