Как я могу определить типы свойств, используя отражение? - PullRequest
35 голосов
/ 06 февраля 2009

Как мне проверить свойство типа, чтобы узнать, является ли он указанным типом?

РЕДАКТИРОВАТЬ: Моя цель - проверить сборку, чтобы увидеть, содержит ли какой-либо из типов в этой сборке свойства, которые являются MyType (или унаследованы от MyType).

Вот трек, по которому я спустился ...

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");

Это компилируется с предупреждением CS0184: данное выражение никогда не относится к указанному типу ('MyType')

Ответы [ 8 ]

56 голосов
/ 06 февраля 2009

Какой тип вас интересует? Тип возвращаемого значения метода / свойства / события и т. Д.

Если это так, я не думаю, что в MemberInfo есть что-то, что позволяло бы вам непосредственно это делать - вам нужно будет использовать и использовать MethodInfo.ReturnType, PropertyInfo.PropertyType, FieldInfo.FieldType, EventInfo.EventHandlerType и любые другие я забыл. (Помните, что сами типы могут быть членами. Не знаете, что вы хотите с ними делать!)

РЕДАКТИРОВАТЬ: Если вас интересует, представляет ли определенный тип MyType или какой-либо подкласс, используйте Type.IsAssignableFrom :

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

РЕДАКТИРОВАТЬ: Теперь, когда мы знаем, что вам нужны свойства, все просто - используйте GetProperties вместо GetMembers. Мне нравится делать отражения с 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);
}

Если вы не фанат LINQ:

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");

Обратите внимание, что вы можете указать флаги привязки для получения закрытых свойств и т. Д.

48 голосов
/ 06 февраля 2009

Хорошо, может быть, я что-то упускаю глупо, но не должно ли это быть:

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

???

2 голосов
/ 06 февраля 2009

Есть несколько способов проверить тип объекта:

1) Используйте оператор is :

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

2) Используйте оператор как :

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

3) Используйте typeof () и GetType () [3 варианта]:

// #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);
}
1 голос
/ 26 апреля 2013

Этот пример из другого аналогичного вопроса значительно упростил мне понимание

If p.PropertyType Is GetType(String) Then

1 голос
/ 06 февраля 2009

Вы ищете:

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

верно?

1 голос
/ 06 февраля 2009

Я думаю, вам нужно что-то вроде этого:

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;
    }
}
0 голосов
/ 20 марта 2014

Это быстрый путь

property.PropertyType.IsGenericType && (typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition()))
&& typeof(<YourType>).IsAssignableFrom(property.PropertyType.GenericTypeArguments[0])
0 голосов
/ 26 апреля 2013

Вы должны использовать is при сравнении экземпляра чего-либо с явно написанным типом:

Department sales = new Department("Sales");

Debug.Assert(sales is Department);

Вам следует использовать typeof, если вы хотите сравнить 2 типа, и вы не можете написать тип явно:

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

Использование is учитывает наследование, typeof не будет.

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
}

Если вы хотите сравнить 2 типа и принять во внимание наследование, вы можете использовать IsAssignableFrom:

Debug.Assert(typeof(Animal).IsAssignableFrom(typeof(Dog))); // true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...