Erhalten Sie den tatsächlichen Rückgabetyp aus einem Ausdruck > Instanz

c# expression-trees reflection

Frage

Ich habe eine Methode, die eine Expression<Func<T, object>> akzeptiert. Ich möchte den tatsächlichen Datentyp ermitteln, der von einer bestimmten Ausdrucksinstanz und nicht von einem object .

Ich kann es für direkte Eigenschaftenreferenzen verwenden, wenn ich den Ausdruck x => x.IntegerProperty kann ich eine x => x.IntegerProperty für eine ganze Zahl erhalten. Dieser Ansatz erfordert die Konvertierung in eine MemberExpression.

Ich kann es jedoch nicht für beliebige Ausdrücke verwenden. Wenn der Ausdruck beispielsweise x => x.IntegerProperty.ToString() möchte ich eine x => x.IntegerProperty.ToString() für eine Zeichenfolge x => x.IntegerProperty.ToString() . Ich kann das nicht zu einem MemberExpression kompilieren, und wenn ich nur .Compile() es und den Rückgabetyp überprüfen, bekomme ich "Objekt".

Wie kann ich die spezifische Ausdrucksinstanz betrachten und den tatsächlichen Rückgabetyp ableiten?

Akzeptierte Antwort

So etwas könnte den Trick machen. Es deckt wahrscheinlich nicht alle Möglichkeiten ab, aber es ist ein Anfang.

public static Type GetObjectType<T>(Expression<Func<T, object>> expr)
{
    if ((expr.Body.NodeType == ExpressionType.Convert) ||
        (expr.Body.NodeType == ExpressionType.ConvertChecked))
    {
        var unary = expr.Body as UnaryExpression;
        if (unary != null)
            return unary.Operand.Type;
    }
    return expr.Body.Type;
}

Beliebte Antwort

Dies ist zwar nicht unmöglich, aber besonders schwierig. Es würde erfordern, den Ausdrucksbaum zu gehen und eine potentiell komplexe Logik auszuführen. Zum Beispiel, was würden Sie sehen wollen, wenn ich den folgenden Ausdruck weitergeben würde?

Func<bool, object> expr = switch => switch ? 1 : "False";

Diese Methode könnte entweder einen int oder eine string .

Jetzt können Sie möglicherweise mehr Fortschritte machen, indem Sie einen Teil dieser Logik auf den Compiler verlagern. Sie könnten Ihren Methodenparameter von Func<T, object> in Func<T, TReturn> und typeof(TReturn) innerhalb der Methode verwenden, um zu bestimmen, wie der Compiler den Rückgabetyp des Ausdrucks festgelegt hat.

Im Fall meines Beispiels arbeiten Sie natürlich immer noch gegen ein object . Aber Ihr Beispiel von x => x.IntegerProperty.ToString() liefert den string , nach dem Sie suchen.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow