it-swarm.com.de

Wie kann ich Eigenschaftstypen mithilfe von Reflektion ermitteln?

Wie teste ich eine Eigenschaft eines Typs, um festzustellen, ob es sich um einen angegebenen Typ handelt?

BEARBEITEN: Mein Ziel ist es, eine Assembly zu untersuchen, um festzustellen, ob einer der Typen in dieser Assembly Eigenschaften enthält, die MyType sind (oder von MyType geerbt wurden).

Hier ist der Track, den ich gegangen bin ...

AssemblyName n = new AssemblyName();
n.CodeBase = "file://" + dllName;
Assembly a = AppDomain.CurrentDomain.Load(n);

foreach (Type t in a.GetTypes())
    foreach (PropertyInfo pi in t.GetProperties())
        if ( pi.PropertyType is MyType ) // warning CS0184
            Console.WriteLine("Found a property that is MyType");

Dies wird mit der Warnung CS0184 kompiliert: Der angegebene Ausdruck ist niemals vom angegebenen Typ ('MyType')

32
Ed Guiness

Für welchen Typ interessieren Sie sich? Der Rückgabetyp der Methode/Eigenschaft/des Ereignisses usw.?

Wenn ja, glaube ich nicht, dass es etwas in MemberInfo gibt, mit dem Sie direkt darauf zugreifen können - Sie müssen Casting und verwenden und MethodInfo.ReturnType, PropertyInfo.PropertyType, FieldInfo.FieldType, EventInfo.EventHandlerType und alle anderen, die ich vergessen habe. (Denken Sie daran, dass Typen selbst Mitglieder sein können. Sie sind sich nicht sicher, was Sie mit ihnen machen möchten!)

BEARBEITEN: Wenn Sie daran interessiert sind, ob ein bestimmter Typ entweder MyType oder eine Unterklasse darstellt, verwenden Sie Type.IsAssignableFrom :

if (typeof(MyType).IsAssignableFrom(type))

BEARBEITEN: Nun, da wir wissen, dass Sie Eigenschaften wünschen, ist es einfach - verwenden Sie GetProperties anstelle von GetMembers. Ich mag Reflexion mit LINQ:

var query = from type in Assembly.GetTypes()
            from property in type.GetProperties()
            where typeof(MyType).IsAssignableFrom(property.PropertyType)
            select new { Type=type, Property=property };

foreach (var entry in query)
{
    Console.WriteLine(entry);
}

Wenn Sie kein Fan von LINQ sind:

foreach (Type t in a.GetTypes())
    foreach (PropertyInfo pi in t.GetProperties())
        if (typeof(MyType).IsAssignableFrom(pi.PropertyType))
            Console.WriteLine("Found a property that is MyType");

Beachten Sie, dass Sie möglicherweise Bindungsflags angeben möchten, um nicht öffentliche Eigenschaften usw. zu erhalten.

55
Jon Skeet

Ok, vielleicht fehlt mir etwas Dummes, aber sollte es nicht sein:

if ( pi.PropertyType == typeof(MyType ))

???

48
BFree

Es gibt mehrere Möglichkeiten, den Objekttyp zu testen:

1) Verwenden Sie den Operator is :

if (anObject is MyType) {
// anObject is MyType or a derived class
... 
}

2) Verwenden Sie den Operator as :

MyType newObject = anObject as MyType;
if (newObject != null ) {
// newObject is anObject cast to MyType
...
}

3) Verwenden Sie typeof () und GetType () [3 Variationen]:

// #1
if (typeof(MyType) == anObject.GetType()) {
// anObject is a MyType
...
}

//#2
public static bool IsType(object obj, string type)
{// modified from Visual C# 2005 Recipes {Apress}
// Get the named type, use case-insensitive search, throw
// an exception if the type is not found.
Type t = Type.GetType(type, true, true);
return t == obj.GetType();
}

//#3
public static bool IsTypeOrSubclass(object obj, string type)
{// modified from Visual C# 2005 Recipes {Apress}
// Get the named type, use case-insensitive search, throw
// an exception if the type is not found.
Type t = Type.GetType(type, true, true);
return t == obj.GetType() || obj.GetType().IsSubclassOf(t);
}
2
rivy

Dieses Beispiel aus der anderen ähnlichen Frage hat mir das Verständnis sehr erleichtert

If p.PropertyType Is GetType(String) Then

1
vlr

Ich denke, du brauchst so etwas:

using System;
using System.Reflection;

namespace ConsoleApplication1{
    class Class1{

        static bool checkType(Type propertyType,Type myType){
            if (propertyType == myType){
                return true;
            }
            Type test = propertyType.BaseType;
            while (test != typeof(Object)){
                if (test == myType){
                    return true;
                }
                test = test.BaseType;
            }
            return false;
        }

        [STAThread]
        static void Main(string[] args){
            Assembly a = Assembly.GetExecutingAssembly();
            foreach (Type t in a.GetTypes()){
                Console.WriteLine("Type: {0}",t.Name);
                foreach (PropertyInfo p in t.GetProperties()){
                    if (checkType(p.PropertyType,typeof(MyType))){
                        Console.WriteLine("  Property: {0}, {1}",p.Name,p.PropertyType.Name);
                    }
                }
            }
        }
    }

    class MyType{
    }

    class MyType2 : MyType{
    }

    class TestType
    {
        public MyType mt{
            get{return _mt;}
            set{_mt = value;}
        }
        private MyType _mt;
        public MyType2 mt2
        {
            get{return _mt2;}
            set{_mt2 = value;}
        }
        private MyType2 _mt2;
    }
}
1
Paolo Tedesco

Du suchst nach:

if (typeof(mi) is MyType) { ... }

recht ?

1
Alexander

Dies ist eine Abkürzung

property.PropertyType.IsGenericType && (typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition()))
&& typeof(<YourType>).IsAssignableFrom(property.PropertyType.GenericTypeArguments[0])

Sie sollten is verwenden, wenn Sie eine Instanz von etwas mit einem explizit geschriebenen Typ vergleichen:

Department sales = new Department("Sales");

Debug.Assert(sales is Department);

Sie sollten typeof verwenden, wenn Sie 2 Typen vergleichen möchten und den Typ nicht explizit schreiben können:

private void CheckType(Type t)
{
    Debug.Assert(typeof(Department) == t);
}

Bei Verwendung von is wird die Vererbung berücksichtigt, typeof wird nicht verwendet.

public class Animal { }
public class Dog : Animal { }

public void Test()
{
    Dog d = new Dog();

    Debug.Assert(d is Animal); // true

    Debug.Assert(typeof(Dog) == typeof(Animal); // false
}

Wenn Sie zwei Typen vergleichen und die Vererbung berücksichtigen möchten, können Sie IsAssignableFrom verwenden:

Debug.Assert(typeof(Animal).IsAssignableFrom(typeof(Dog))); // true
0
PeteGO