Ausdrucksbaum mit Eigenschaftenvererbung verursacht eine Argumentausnahme

.net expression-trees linq

Frage

Nach diesem Beitrag: Linktext Ich versuche eine Ausdrucksstruktur zu erstellen, die auf die Eigenschaft einer Eigenschaft verweist. Mein Code sieht so aus:

public interface IFoo
{
    void X {get;set;}
}

public interface IBar : IFoo
{
    void Y {get;set;}
}

public interface IFooBarContainer
{
    IBar Bar {get;set;}
}

public class Filterer
{
     //Where T = "IFooBarContainer"
     public IQueryable<T> Filter<T>(IEnumerable<T> collection)
     {
              var argument = Expression.Parameter(typeof (T), "item");

              //...

               //where propertyName = "IBar.X";
               PropertyOfProperty(argument, propertyName); 
     }

        private static MemberExpression PropertyOfProperty(Expression expr, string propertyName)
        {
            return propertyName.Split('.').Aggregate<string, MemberExpression>(null, (current, property) => Expression.Property(current ?? expr, property));
        }
}

Ich erhalte die Ausnahme:

System.ArgumentException: Die Instanzeigenschaft 'X' ist für den Typ 'IBar' nicht definiert.

ReSharper hat den Code im obigen Link in die komprimierte Anweisung in meinem Beispiel umgewandelt. Beide Formen der Methode haben den gleichen Fehler zurückgegeben.

Wenn ich IBar.Y referenziere, IBar.Y die Methode nicht fehl.

Akzeptierte Antwort

Die Eigenschaft, auf die Sie zugreifen IBar.X , ist nicht IBar.X , sondern IFoo.X Die Expression.Property Methode erwartet den tatsächlichen Typ, der die Eigenschaft deklariert, und nicht einen Subtyp. Wenn Sie nicht überzeugt sind, versuchen Sie Folgendes:

var prop = typeof(IBar).GetProperty("X");

Es gibt null zurück (nur weil IBar eine Schnittstelle ist; es würde für eine Klasse funktionieren)

Ich denke, der einfachste Weg, um es zum Laufen zu bringen, besteht darin, eine Hilfsmethode zu erstellen, um die tatsächliche Eigenschaft aufzulösen, indem man die Typhierarchie rekursiv nach oben führt:

var prop = typeof(IBar).GetProperty("X");

Sie können dann Ihre PropertyOfProperty wie folgt neu schreiben:

var prop = typeof(IBar).GetProperty("X");



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum