8 votes

Comment définir le dictionnaire d'ExpandoObject comme insensible à la casse?

Étant donné le code ci-dessous

dynamic e = new ExpandoObject();
var d = e as IDictionary;
for (int i = 0; i < rdr.FieldCount; i++)
   d.Add(rdr.GetName(i), DBNull.Value.Equals(rdr[i]) ? null : rdr[i]);

Y a-t-il un moyen de le rendre insensible à la casse afin que le nom du champ soit employee_name

e.Employee_name fonctionne aussi bien que e.employee_name

Il ne semble pas y avoir de moyen évident, peut-être une astuce ?

10voto

J'ai utilisé cette classe “Flexpando” (pour extensible flexible) qui est insensible à la casse.

C'est similaire à la réponse de Darin's MassiveExpando en ce sens qu'elle vous offre un support de dictionnaire, mais en exposant cela comme un champ, cela vous évite d'avoir à implémenter une quinzaine de membres pour IDictionary.

public class Flexpando : DynamicObject {
    public Dictionary Dictionary
        = new Dictionary(StringComparer.OrdinalIgnoreCase);

    public override bool TrySetMember(SetMemberBinder binder, object value) {
        Dictionary[binder.Name] = value;
        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result) {
        return Dictionary.TryGetValue(binder.Name, out result);
    }
}

2 votes

J'aime la simplicité mais je pense qu'il devrait y avoir un peu plus de contrôle sur les internes. Peut-être deux constructeurs, un vide qui défaut à ce que vous avez ici et un qui prend un IDictionary, chaque constructeur définit le champ Dictionary, que je changerais en une propriété publique avec un setter privé.

5voto

Darin Dimitrov Points 528142

Vous pouvez consulter l'implémentation de Massive d'un MassiveExpando qui est un objet dynamique insensible à la casse.

0 votes

Intéressant, je n'étais pas au courant de cette branche de massive, cela n'a pas été mis à jour depuis février, je vais donc examiner les différences, merci !

1voto

xanatos Points 30513

Plus par curiosité que comme solution:

dynamic e = new ExpandoObject();
var value = 1;
var key = "Clé";

var resul1 = RuntimeOps.ExpandoTrySetValue(
    e, 
    null, 
    -1, 
    value, 
    key, 
    true); // Le dernier paramètre est ignoreCase

object value2;
var result2 = RuntimeOps.ExpandoTryGetValue(
    e, 
    null, 
    -1, 
    key.ToLowerInvariant(), 
    true, 
    out value2);  // Le dernier paramètre est ignoreCase

RuntimeOps.ExpandoTryGetValue/ExpandoTrySetValue utilisent des méthodes internes de ExpandoObject qui peuvent contrôler la sensibilité à la casse. Les paramètres null, -1, sont pris des valeurs utilisées en interne par ExpandoObject (RuntimeOps appelle directement les méthodes internes de ExpandoObject)

N'oubliez pas que ces méthodes sont Cette API prend en charge l'infrastructure du .NET Framework et n'est pas destinée à être utilisée directement à partir de votre code.

0 votes

Obsolète ne compile pas dans .net 4 msdn.microsoft.com/fr-fr/library/dd782193.aspx

0 votes

@Kumar Je dois dire la vérité... Oui, j'ai testé le code sur Visual Studio 2010 et ça a fonctionné. Juste pour être sûr, ce matin je l'ai testé à nouveau et ça a fonctionné :-) Intéressant, les ExpandoTryGetValue et ExpandoTrySetValue ne sont pas marqués comme obsolètes sur mon ordinateur donc je n'ai reçu aucun avertissement.

0 votes

Hmm, intéressant, pas sûr de ce qui pourrait être différent ici! Je n'ai pas pu compiler, alors je suis allé chercher des réponses et j'ai trouvé la page msdn! J'ai vs2010 ultimate sp1 sur xp sp3! Il n'y a pas de bêta ou quoi que ce soit sur ce pc non plus et pas familier d'un .net 4 sp1 ou aperçu non plus, des pensées ?

0voto

RBZ Points 526
public static class IDictionaryExtensionMethods
{
  public static void AddCaseInsensitive(this IDictionary dictionary, string key, object value)
  {
    dictionary.Add(key.ToUpper(), value);
  }

  public static object Get(this IDictionary dictionary, string key)
  {
    return dictionary[key.ToUpper()];
  }
}

0voto

Abbondanza Points 800

Une autre solution consiste à créer une classe similaire à ExpandoObject en dérivant de System.Dynamic.DynamicObject et en remplacant les méthodes TryGetValue et TrySetValue.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X