Frage

ich arbeite an einem Verfahren, das einen Ausdrucksbaum als Parameter übernimmt, zusammen mit einer Art (oder Instanz) eine Klasse.

Die Grundidee ist, dass diese Methode, bestimmte Dinge zu einer Sammlung hinzufügen wird, die für die Validierung verwendet wird.

public interface ITestInterface
{
    //Specify stuff here.
}

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

Das Verfahren wird wie folgt aufgerufen:

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());
}

Ich mache es auf diese Weise, weil ich für die Eigenschaftsnamen möchten, die übergeben werden stark typisierte sein.

Ein paar Dinge, die ich bin zu kämpfen mit ..

  1. Im DoSomething, würde Ich mag einen PropertyInfo Typen erhalten von T (aus dem Körper geleitet in) und fügen Sie ihn in eine Sammlung zusammen mit Regel []. Derzeit Ich denke an expression.Body mit und Entfernen von [Eigenschaftsname] von „Convert. ([Eigenschaftsname])“ und die Reflexion zu bekommen, was ich brauche. Dies scheint umständlich und falsch. Gibt es einen besseren Weg?
  2. Ist das ein bestimmtes Muster ich verwende?
  3. Schließlich irgendwelche Vorschläge oder Präzisierungen zu meinem Missverständnis von dem, was ich tue, werden geschätzt und / oder Ressourcen oder gute Informationen über C # Ausdruck Bäume werden auch geschätzt.

Danke!

Ian

Edit:

Ein Beispiel dafür, was expression.Body.ToString() kehrt innerhalb der DoSomething Methode ist eine Zeichenfolge, die „Convert (t.MyProperty)“, wenn aus dem obigen Beispiel genannt enthält.

Ich brauche es dringend eingegeben werden, so wird es nicht kompilieren, wenn ich einen Eigenschaftsnamen ändern.

Danke für die Vorschläge!

War es hilfreich?

Lösung

Das Sammeln Propertyinfo-Objekte aus Expression.Body scheint ähnlich wie meine Lösung auf eine andere Frage.

Andere Tipps

I stützen sich stark auf die Expression Bäume viel zu schieben, was ich will mit meiner aktuellen Anwendung tun zu Zeit kompilieren, das heißt statische Typprüfung.

ich durchqueren Ausdruck Bäume sie in etwas anderes zu übersetzen, die „Sinn macht“.

Eine Sache, die ich beendet habe viel zu tun up ist, dass anstelle von URLs, die ich auf einem MVC verlassen wie Ansatz, bei dem ich Lambda-Funktionen erklären und übersetzt, dass ... interpretieren, der Compiler erzeugte Ausdrucksbaum in eine URL. Wenn diese URL aufgerufen wird, kann sie das Gegenteil. Auf diese Weise habe ich, was ich kompilieren Zeitprüfungen für defekte Links und funktioniert dies sehr gut mit Refactoring und auch Überlastungen. Ich denke, es ist cool über die Verwendung von Ausdrucksbaumstrukturen auf diese Weise zu denken.

Sie wollen vielleicht das Besuchermuster überprüfen, es ist ein Schmerz, mit zu beginnen, weil es nicht viel Sinn am Anfang machen, aber es bindet alles zusammen und es ist eine sehr formale Art und Weise Typprüfung in Compiler Konstruktion zu lösen. Sie könnten das gleiche tun, aber anstatt Typprüfung emittieren, was auch immer Sie brauchen.

Etwas, was ich momentan meinen Kopf bin hämmern gegen ist die Fähigkeit, einen einfachen Rahmen für die Übersetzung zu bauen (oder eigentlich sollte ich sagen interpretieren) Ausdruck Tress und emittieren JavaScript. Die Idee ist, dass der Compiler erzeugte Ausdrucksbäume in gültige JavaScript übersetzen wird, die mit einem Objekt-Modell-Schnittstellen.

Was ist das spannend ist, ist die Art und Weise der Compiler immer in der Lage ist, mir zu sagen, wenn ich falsch und sicher das Endergebnis gehen ist nur ein Haufen von Strings, aber der wichtige Teil ist, wie diese Strings wurde erstellt. Sie gingen durch einige Überprüfung und das bedeutet etwas.

Sobald Sie, dass es geht wenig Sie nicht mit Ausdruck Bäume tun können.

Während der System.Reflection.Emit Sachen arbeiten fand ich mich Ausdruck Bäume mit einem leichtgewichtigen Rahmen für dynamische Zusammenstellung zu schaffen, die im Grunde bei der Kompilierung sagen könnten, wenn mein dynamisch erstellten Baugruppen sowie kompilieren würde, und das funktionierte nahtlos mit Reflexion und statische Typprüfung. Es dauerte dies weiter und weiter und endete mit etwas, das am Ende viel Zeit gespart und erwies sich als sehr agil und robust sein.

So liebe ich diese Art von Sachen, und das ist, was Meta-Programmierung überhaupt geht, ist Programme in Ihre Programme zu schreiben, die Programme tun. Ich sage halten es kommt!

ich zu schätzen, was Sie versuchen, hier mit der Eigenschaft zu tun. Ich habe in diesem Rätsel laufen. Es fühlt sich immer komisch zu schreiben:

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

Wenn die Eigenschaft jemals Namen ändert, oder der Text in dem Aufruf falsch eingegeben, dann wird es ein Problem sein. Was ich bin gekommen, zu lernen, ist, dass dies etwas, das Sie wahrscheinlich mit über Tests zu tun haben. Insbesondere Komponententests. Ich würde schreiben Unit-Tests zu erzwingen, dass die „DoSomething“ Anrufe korrekt funktionieren.

Die andere Sache, die Sie versuchen könnte, ist Ihre Eigenschaften mit Attributen dekorieren, und dann gegen die Klasse widerspiegeln, wenn es Objekte mit dem Attribut und Laderegeln suchen aufgebaut ist.

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

In diesem Fall wird der Konstruktor (vielleicht in einer Basisklasse?) Würde dynamisch ein Other Objekt und ein OtherClass2 Objekt erstellen und sie in eine Sammlung lädt zusammen mit dem Namen der Eigenschaft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top