4 Stimmen

C# Reflection Performence Hilfe

        var property = obj.GetType().GetProperty(blockName);

        if (property == null)
        {
            var method = obj.GetType().GetMethod(blockName);

            if (method == null)
                return "[" + blockName + "]";
            else
                return method.Invoke(obj, null).ToString();
        }
        else
            return property.GetValue(obj, null).ToString();

Dieser Code sollte nach einer Eigenschaft namens blockName den Wert. Wenn die Eigenschaft gefunden wird, sollte sie ihren Wert zurückgeben. Wenn nicht, sollte es nach der Funktion namens blockName den Wert. Wenn er ihn findet, sollte er ihn aufrufen und den zurückgegebenen Wert zurückgeben. Wenn es die Methode nicht findet, sollte es [ blockName's value ].

Es funktioniert gut, aber ich suche nach Möglichkeiten, es effizienter zu machen. Ich möchte keine Methoden in Eigenschaften oder Eigenschaften in Methoden umwandeln, weil ich in Zukunft auch Parameter hinzufügen werde. Können Sie mir bitte helfen?

Danke.

7voto

Marc Gravell Punkte 970173

Wenn Sie die Signaturen kennen (d. h. den Rückgabetyp und die Parameter), dann Delegate.CreateDelegate kann hier sehr effektiv eingesetzt werden:

using System;
using System.Reflection;
class Test
{
    public string Foo(int i)
    {
        return i.ToString();
    }
    static void Main()
    {
        MethodInfo method = typeof(Test).GetMethod("Foo");
        Func<Test, int, string> func = (Func<Test, int, string>)
            Delegate.CreateDelegate(typeof(Func<Test, int, string>), null, method);
        Test t = new Test();
        string s = func(t, 123);

    }
}

Beachten Sie, dass Sie bei den Eigenschaften die folgenden Punkte beachten sollten GetGetMethod y GetSetMethod . Dies funktioniert nicht so gut, wenn Sie die Signatur nicht kennen, da DynamicInvoke ist sehr langsam.

Um von folgenden Vorteilen zu profitieren Delegate.CreateDelegate Sie なければならない Zwischenspeichern und Wiederverwenden der Delegateninstanz; erstellen Sie sie nicht jedes Mal neu!

Bei Immobilien, auch wenn Sie den Immobilientyp nicht kennen, sollten Sie vielleicht Folgendes in Betracht ziehen HyperDeskriptor (Sie müssen die 1-Zeile hinzufügen, um den Hyper-Deskriptor zu aktivieren):

using System.ComponentModel;
class Test
{
    public int Bar { get; set; }
    static void Main()
    {
        PropertyDescriptor prop = TypeDescriptor.GetProperties(
            typeof(Test))["Bar"];
        Test t = new Test();
        t.Bar = 123;
        object val = prop.GetValue(t);
    }
}

4voto

Ray Burns Punkte 60870

Ihr Hauptproblem ist, dass Type.GetProperty(...) und Type.GetMethod(...) extrem langsam sind. Wenn Sie die von diesen Methoden zurückgegebenen Werte zwischenspeichern, werden Sie einen enormen Geschwindigkeitszuwachs feststellen (etwa 20x schneller für diesen Code).

Obwohl MethodInfo.Invoke und PropertyInfo.GetValue langsamer sind als direkte Aufrufe, sind sie für die meisten Zwecke ausreichend schnell. Optimieren Sie sie nur mit dynamischen Assemblies, wenn Sie wirklich müssen - es ist eine Menge Arbeit.

2voto

Nader Shirazie Punkte 10691

Eine Möglichkeit, dies zu tun, besteht darin, bei der ersten Ausführung dieses Codes eine dynamische Methode zu emittieren und sie zwischenzuspeichern. Bei den folgenden Aufrufen wird dann die vorgenerierte Methode ausgeführt, was ziemlich schnell ist. Wenn die wiederholte Ausführung dieses Codes das Problem ist, das Sie sehen, dann kann dieser Ansatz gut für Sie funktionieren. Und bitte verzeihen Sie mir, wenn ich die Erklärung missverstanden habe.

Werfen Sie einen Blick auf die Bibliothek für dynamische Reflexion auf Codeplex.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X