Question

Je travaille sur une méthode qui accepte un arbre d'expression en tant que paramètre, ainsi qu'un type (ou une instance) d'une classe.

L'idée de base est que cette méthode ajoute certaines choses à une collection qui sera utilisée pour la validation.

public interface ITestInterface
{
    //Specify stuff here.
}

private static void DoSomething<T>(Expression<Func<T, object>> expression, params IMyInterface[] rule)
{
    // Stuff is done here.
}

La méthode est appelée comme suit:

class TestClass
{
    public int MyProperty { get; set; }
}

class OtherTestClass  : ITestInterface
{
    // Blah Blah Blah.
}

static void Main(string[] args)
{
    DoSomething<TestClass>(t => t.MyProperty, 
        new OtherTestClass());
}

Je le fais de cette façon parce que j'aimerais que les noms de propriétés qui sont transmis soient fortement typés.

Quelques problèmes avec lesquels je me bats ..

  1. Dans DoSomething, j'aimerais obtenir un type PropertyInfo (du corps transmis) de T et l'ajouter à une collection avec la règle []. Actuellement, je songe à utiliser expression.Body et à supprimer le [nom de domaine] de "Convert. ([Nom de domaine])". et en utilisant la réflexion pour obtenir ce dont j'ai besoin. Cela semble lourd et faux. Y a-t-il un meilleur moyen?
  2. Est-ce un motif spécifique que j'utilise?
  3. Enfin, toutes les suggestions ou clarifications relatives à mon incompréhension de ce que je fais sont appréciées et / ou les ressources ou les bonnes informations sur les arbres d’expression C # sont également appréciées.

Merci!

Ian

Modifier:

Un exemple de ce que expression.Body.ToString () renvoie dans la méthode DoSomething est une chaîne qui contient le message "Convertir (t.MyProperty)". si appelé à partir de l'exemple ci-dessus.

J'ai besoin que cela soit fortement typé pour qu'il ne soit pas compilé si je change le nom de la propriété.

Merci pour les suggestions!

Était-ce utile?

La solution

La collecte d'objets PropertyInfo à partir de Expression.Body semble similaire à ma solution à une autre question.

Autres conseils

Je compte énormément sur les arbres d'expression pour pousser beaucoup de ce que je veux faire avec mon application actuelle à la compilation, à savoir la vérification de type statique.

Je traverse les arbres d'expression pour les traduire en quelque chose d'autre qui "a du sens".

Une chose que j’ai souvent fait est que, au lieu d’URL, je me fie à une approche de type MVC dans laquelle je déclare des fonctions lambda et traduis ... interprétant, l’arbre d’expression généré par le compilateur en une URL. Lorsque cette URL est invoquée, je fais le contraire. De cette façon, j'ai ce que j'appelle des vérifications au moment de la compilation pour les liens brisés et cela fonctionne très bien avec le refactoring et les surcharges. Je pense que c'est cool de penser à utiliser les arbres d'expression de cette façon.

Vous voudrez peut-être vérifier le modèle de visiteurs, c'est difficile de commencer car cela n'a pas beaucoup de sens au début, mais cela lie tout ensemble et c'est un moyen très formel de résoudre le contrôle de texte dans la construction du compilateur. Vous pouvez faire la même chose, mais au lieu de vérifier le type, émettez ce dont vous avez besoin.

Quelque chose contre lequel je me bats actuellement la tête est la possibilité de construire un cadre simple pour traduire (ou en fait, je devrais dire interpréter) tress d'expression et émettre du JavaScript. L’idée est que les arbres d’expression générés par le compilateur se traduisent par un code JavaScript valide qui s’interface avec un modèle d’objet.

Ce qui est enthousiasmant, c’est la façon dont le compilateur est toujours capable de me dire quand j’ai mal tourné et que le résultat final n’est qu’un tas de chaînes, mais l’important est la manière dont ces chaînes ont été créées. Ils ont subi une vérification et cela signifie quelque chose.

Une fois que vous y parvenez, vous ne pouvez plus rien faire avec les arbres d'expression.

Tout en travaillant avec les éléments System.Reflection.Emit, je me suis retrouvé à utiliser des arbres d'expression pour créer un cadre léger pour la compilation dynamique, ce qui, au moment de la compilation, pouvait en principe indiquer si mes assemblys créés de manière dynamique compileraient également, et cela a fonctionné. de manière transparente avec réflexion et vérification de type statique. Cela a pris de plus en plus loin et a abouti à quelque chose qui a finalement permis d'économiser beaucoup de temps et s'est révélé très agile et robuste.

Donc, j'aime ce genre de choses, et c'est en cela que consiste la méta-programmation, écrire des programmes dans vos programmes qui font des programmes. Je dis, continuez!

J'apprécie ce que vous essayez de faire avec la propriété ici. J'ai couru dans cette énigme. C'est toujours bizarre d'écrire:

DoSomething("MyProperty", new OtherClass());

Si la propriété change jamais de nom ou si le texte est mal saisi lors de l'appel, il y aura un problème. Ce que j’ai appris, c’est que c’est un problème auquel vous devez probablement faire face au moyen de tests. Plus précisément, les tests unitaires. J'écrirais des tests unitaires pour faire en sorte que le " DoSomething " les appels fonctionnent correctement.

Vous pouvez également essayer de décorer vos propriétés avec des attributs, puis de les comparer à votre classe lorsqu'elle est construite à la recherche de propriétés avec l'attribut et de règles de chargement.

[DoSomething(typeof(OtherClass), typeof(OtherClass2))]
public int MyProperty
{
  get;
  set;
}

Dans ce cas, le constructeur (peut-être dans une classe de base?) créerait dynamiquement un objet OtherClass et un objet OtherClass2, et les chargerait dans une collection avec le nom de la propriété.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top