C# Reflection - Zugriff auf Variablen und Methoden

dammi

Lt. Commander
Dabei seit
Sep. 2007
Beiträge
1.624
Hallo zusammen,

ich bin gerade gezwungen ein Plugin in C# zu schreiben und stocke gerade etwas mit dem Umgang der tollen Reflection Bibliothek :-)

Ich will nichts weiter, als alle Variablen und Methoden via Reflection abzufragen und später eventuell wieder darauf zuzugreifen / aufzurufen.

Angenommen ich habe die Klasse "ReflectionsTest" mit ein paar Variablen und Methoden alá:
Code:
 public class ReflectionTest
    {
        protected String anyVar1;
        protected String anyVar2;
        protected String anyVar3;

        public ReflectionTest()
        {
             ...
        }

        public void anyMethod()
        {
             ...
        }
    }
so sollte es ja möglich sein die Variablen und Methoden dieser Klasse via Reflection zu erzahlten & aufzurufen!

Leider funktioniert schon das Abfragen der Variablen nicht, zusammen gegoogelt habe ich mir folgenden Aufruf (in meinem Fall innerhalb des Konstruktors "ReflectionTest()":

Code:
Type type = this.GetType();

FieldInfo[] fields = type.GetFields();

foreach (FieldInfo field in fields)
{
    System.Diagnostics.Debug.WriteLine("+ " + field.Name.ToString());
}
Analog dazu, bei den Methoden:

Code:
Type type = this.GetType();

MethodInfo[] methods = type.GetMethods();

foreach (MethodInfo method in methods)
{
    System.Diagnostics.Debug.WriteLine("+ " + method.Name.ToString());
}
Der Aufruf sollte hier ja dann via der mitgeliferten invoke() Methode realisiert werden können, allerdings bekomme ich ja nicht einmal die Variablen & Methoden, also brauch ich mir über den Methodenaufruf noch garkeine Gedanken zu machen :D

Kann mir jemand sagen, was ich falsch mache?
 
Zuletzt bearbeitet:
1

1668mib

Gast
"Funktioniert nicht" ist keine Fehlerbeschreibung - auch nicht nachts... Was konkret geht denn nicht? Kommt keine Ausagabe (dann einfach mal auf System.Console.WriteLine wechseln)... Werden die privaten Felder nicht zurückgegeben? Wundert ja nicht, weil du das gar nicht verlangst...

Schon mal auf die Idee gekommen, auch mal die offizielle Dokumentation zu lesen?
http://msdn.microsoft.com/de-de/library/ch9714z3(v=vs.80).aspx


Code:
using System;
using System.Reflection;

namespace ReflectionTest
{
   class Program
    {
        static void Main(string[] args)
        {
            TestClass testClass = new TestClass();
            Console.WriteLine("testClass: " + testClass.ToString());

            Type type = testClass.GetType();
            Console.WriteLine("Is Class: " + type.IsClass);

            BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
            FieldInfo[] fields = type.GetFields(flags);
            Console.WriteLine(fields.Length);
            
            foreach (FieldInfo field in fields)
            {
                System.Console.WriteLine("+ " + field.Name.ToString());
                field.SetValue(testClass, 2);
            }

            Console.WriteLine("testClass: " + testClass.ToString());
            Console.ReadKey();
        }
    }

    class TestClass
    {
        private int value;
        public int publicValue;

        public TestClass()
        {
            this.value = 1;
        }

        public override String ToString()
        {
            return value.ToString();
        }
    }
}
 
Zuletzt bearbeitet:

dammi

Lt. Commander
Ersteller dieses Themas
Dabei seit
Sep. 2007
Beiträge
1.624
Das hast Du natürlich vollkommen Recht :-) Das Problem war, dass GetFields() entweder kein Ergebnis lieferte, oder mir nur von Object vererbte Methoden mitgegeben hat (toString(), GetType(), GetHashCode() etc.)

Dokumentation hatte ich selbstverständlich gelesen, nur darüber kam ich auf die "korrekte" Verwendung, da im Inet ja gefühlte 5 Mio. versch. Varianten existieren.

Vielen Dank für Deinen Beispielcode, es lag schlichtweg an der Verwendung der BindingFlags,

Ich hatte an es an dieser Stelle nur mal mit ".NonPublic", ".Instance" und ".DeclaredOnly" (im einzelnen) versucht - und da lag wohl auch der Fehler: Man muss, wie Du angegeben hast, alle von Dir genannten Flags deklarieren um auch die protected Variablen zu bekommen (was ich an dieser Stelle etwas unlogisch finde und auch so nicht aus der MSDN Doku herausgelesen hatte).

Vielen Dank für Deine Mühe so früh morgens :-)
 

holy

Lieutenant
Dabei seit
Aug. 2008
Beiträge
533
Nur als Ergänzung.
Du schreibst du entwickelst ein Plugin. Wäre es für dich nicht deutlich einfacher, sich per Interface auf einen Contract zu einigen und dann das Plugin/Lib per Reflection (Assembly.Load) zu laden? Je nach Größe deines Projekts bzw. Anzahl der Plugins sogar über MEF oder Unity?
 

dammi

Lt. Commander
Ersteller dieses Themas
Dabei seit
Sep. 2007
Beiträge
1.624
Selbstverständlich wäre das einfacher und vorallem sinnvoller, allerdings handelt es sich hier um die Entwicklung eines Mini-Plugins für das Multitool der ESL - ESL-Wire. An den vorhandenen Schnittstellen wird soweit ich weiß auch nicht einmal mehr aktiv entwickelt.

Das mit der Pluginentwicklung ist an dieser Stelle auch eher zweitrangig, da es sich bei der Verwendung der Reflection um meine eigenen Klassen handelt, die ich so dynamisch/generisch wie möglich aufbauen möchte.

Es ist einfach nur ein Spassprojekt und nichts Ernstes, in das ich viel Zeit investieren möchte. Auch bin ich kein C#, sondern ein Java Entwickler :-)

Aber vielen Dank für Eure Hilfe und Anregungen!
 
Zuletzt bearbeitet:
Top