J'utilise .NET 3.5. Nous avons des classes tierces complexes qui sont automatiquement générées et hors de mon contrôle, mais que nous devons travailler à des fins de test. Je vois que mon équipe fait beaucoup de biens profondément imbriqués, d'obtenir / de fixer notre code de test, et il devient assez encombrant.
Pour remédier au problème, je voudrais faire une interface fluide pour définir les propriétés sur les différents objets. dans l'arbre hiérarchique. Il existe un grand nombre de propriétés et de classes dans cette bibliothèque tierce, et il serait trop fastidieux de tout cartographier manuellement. P>
Ma pensée initiale était de simplement utiliser des initialisateurs d'objets. qui fonctionne pour initialiser le mais cela ne va pas bien, car je dois définir une méthode pour chaque propriété que je veux définir, et il y a des centaines de propriétés différentes dans toutes les classes. En outre, c # n'a pas de moyen de définir dynamiquement des méthodes avant c # 4, donc je ne pense pas que je puisse me connecter à des choses pour le faire automatiquement d'une manière ou d'une autre. P> Troisième tentative: P > rouge code>,
bleu code> et
vert code> sont des propriétés et
mix () code> est une méthode qui définit une quatrième propriété Couleur Code> à la couleur de sécurité RVB la plus proche avec cette couleur mélangée. Les peintures doivent être homogénéisées avec
remous () code> avant qu'ils puissent être utilisés. P>
peinture code>, Mais j'ai besoin de chaîner
mix () code> et d'autres méthodes à elle. Tentative suivante: p>
Create<Bucket>(Create<Paint>().Set(p => {
p.Red = 0.4;
p.Blue = 0.2;
p.Green = 0.1;
}).Mix().Stir()
)
4 Réponses :
Est-ce que cela fonctionne?
Bucket b = new Bucket() { Paint = new Paint() { Red = 0.4; Blue = 0.2; Green = 0.1; }.Init(p => { p.Mix().Stir(); }) };
Dans Retrospect, cela semble être une approche évidente. Je dois manquer la forêt pour les arbres de regarder cela trop longtemps!
FYI pour ceux qui sont perplexes par @Chis code>: le
@ code> signifie "Traitez le jeton suivant comme identifiant littéral" (pas comme mot clé). L'effet est de nommer un paramètre appelé
ceci code>.
Je ne suis pas perplexe par cela, mais je ne vois aucune raison de combattre le compilateur ici lorsque vous pouvez utiliser un nom équivalent comme auto code> ou
source code>. Sinon, bonne réponse et +1.
Je penserais de cela de cette façon:
Vous voulez essentiellement que votre dernière méthode dans la chaîne retourne un seau. Dans votre cas, je pense que vous voulez que la méthode soit mélangée (), comme vous pouvez remuer () le godet après p> de sorte que vous devez définir au moins une couleur avant vous appelez mix (). Forcons cela avec certaines interfaces de syntaxe. P> et appliquons-les au godetBuilder p> et c'est à peu près tout, vous avez maintenant une interface fluide avec les paramètres RVB en option (tant que vous entrez au moins une) en tant que Bonus. P> CreateBucket.UsingPaint.Red(0.4).Green(0.2).Mix().Stir();
J'utiliserais la méthode d'extension init parce que vous pouvez toujours jouer avec le délégué.
Enfer, vous pouvez toujours déclarer des méthodes d'extension qui prennent des expressions et jouent même avec les expresions (stockez-les pour plus tard, modifiez, peu importe)
De cette façon, vous pouvez facilement stocker des grups par défaut comme: de cette façon, vous pouvez utiliser toutes les actions (ou Funcs) et mettre en cache des initialisateurs standard comme chaînes d'expression pour plus tard? p> p>
Si vous voulez vraiment pouvoir chaîner des paramètres de propriété sans avoir à écrire une tonne de code, une façon de le faire serait d'utiliser la génération de code (CODEDOM). Vous pouvez utiliser la réflexion pour obtenir une liste des propriétés mutables, générer une classe de constructeur fluide avec une méthode finale i ' m Vous allez sauter sur tous les trucs de la chaudière sur la façon d'enregistrer l'outil personnalisé - c'est assez facile à trouver la documentation sur mais toujours à long terme et je ne pense pas que je puisse ajouter grand chose en y compris. Je vais vous montrer ce que je pense pour le codegen cependant. P> Build () code> qui renvoie la classe que vous essayez réellement de créer.
MyCompany.MyProject.Paint
MyCompany.MyProject.Foo
MyCompany.MyLibrary.Bar
En fait, j'ai une approche similaire dans l'un de mes projets.