2010-08-27 10 views
1

Je souhaite créer une méthode d'assistance généralisée pour le chargement et la validation LoadFromXML. Si le XML que je charge est incomplet, je veux qu'il échoue complètement sans lancer une exception. À l'heure actuelle, mon code ressemble à ceci (plus ou moins)Passer des propriétés en tant que paramètres

public override bool Load(XElement source) 
{ 
    return new List<Func<XElement, bool>> 
    { 
     i => this.LoadHelper(i.Element(User.XML_Username), ref this._username, User.Failure_Username), 
     i => this.LoadHelper(i.Element(User.XML_Password), ref this._password, User.Failure_Password) 
     //there are many more invokations of LoadHelper to justify this architecture 
    } 
    .AsParallel() 
    .All(i => i.Invoke(source)); 
} 

private bool LoadHelper(XElement k, ref string index, string failure) 
{ 
    if (k != null && k.Value != failure) 
    { 
     index = k.Value; 
     return true; 
    } 
    return false; 
} 

this._username est une variable de membre privé qui est utilisé par la propriété this.Username. C'est la solution actuelle que j'ai pour ce problème, mais je suis confronté à un problème majeur: Puisque je ne peux pas passer la propriété elle-même au LoadHelper et Action<string> ne correspond pas à la propriété :(, je contourne la logique de réglage de la propriété droite . maintenant

pour vos rêveries, avant l'abstraction LoadHelper, chacune de mes entrées de List<Func<XElement, bool>> avait l'air comme ça ...

i => ((Func<XElement, bool>)(k => { if (k == null || k.Value == User.Failure_Username) return false; 
        { this.Username = k.Value; return true; } })).Invoke(i.Element(User.XML_Username)), 

question: Est-ce que quelqu'un sait quelle façon de le faire sans se soustraire de la propriété logique de réglage?

Répondre

4

action ne correspond pas à la propriété

Si je lis ce droit, vous avez essayé de remplacer le "index de ref string", avec "Action<string>", puis essayé passer le Protperty. Proche mais pas tout à fait. Comment?

private bool LoadHelper(XElement k, Action<string> setter, string failure) 
{ 
    if (k != null && k.Value != failure) 
    { 
     setter(k.Value); 
     return true; 
    } 
    return false; 
} 

puis

i => this.LoadHelper(i.Element(User.XML_Username), s=>{this.Username = s}, 
          User.Failure_Username),  
+0

Wow. Oui tu l'as. Ça y est ...! Merci une tonne mate! – Squirrelsama

+1

N'est-il pas dommage que vous ne puissiez pas traiter les propriétés de façon très classe comme des «délégués » ou «Func »? Certainement l'un de mes points de friction les plus irritants sur C#. – mquander

+0

Je ne pouvais pas être plus d'accord. Je comprends pourquoi - C# devrait en déduire un peu trop sur le paramètre (que ce soit une action ou Func ) pour savoir comment C# est statiquement typé. Mais encore ... Nous devrions pétitionner Microsoft pour changer cela! :RÉ – Squirrelsama

1

Je suis parfois demandé combien il enfler les choses pour .Net pour soutenir une interface iPropriété (T) avec deux membres, et ECRIRE et envelopper automatiquement les champs et propriétés de sorte qu'un paramètre iProperty (of T) puisse être passé un champ ou une propriété.

En utilisant des méthodes anonymes, on pourrait créer une telle chose pas trop horriblement en créant une classe xProperty dont le constructeur a pris les méthodes nécessaires pour obtenir et définir une propriété. On pourrait définir des instances de la classe pour toutes les propriétés que l'on voulait que les autres classes puissent manipuler directement. Les choses seraient bien mieux, s'il y avait une interface standard. Malheureusement, je ne suis pas au courant d'un existant.