C# 如何使用反射确定属性类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/520400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 06:34:24  来源:igfitidea点击:

How can I determine property types using reflection?

c#.netreflection

提问by Ed Guiness

How would I test a property of a type to see if it is a specified type?

我将如何测试类型的属性以查看它是否是指定的类型?

EDIT: My goal is to examine an assembly to see if any of the types in that assembly contain properties that are MyType (or inherited from MyType).

编辑:我的目标是检查程序集以查看该程序集中的任何类型是否包含 MyType(或从 MyType 继承)的属性。

Here is the track I've gone down...

这是我走过的路...

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

This compiles with warning CS0184: The given expression is never of the provided ('MyType') type

编译时出现警告 CS0184:给定的表达式永远不是提供的 ('MyType') 类型

采纳答案by Jon Skeet

What type are you interested in? The return type of the method/property/event etc?

你对什么类型感兴趣?方法/属性/事件等的返回类型?

If so, I don't think there's anything in MemberInfoto let you get at it directly - you'll need to cast and use MethodInfo.ReturnType, PropertyInfo.PropertyType, FieldInfo.FieldType, EventInfo.EventHandlerTypeand any others I've forgotten. (Remember that types themselves can be members. Not sure what you'll want to do with them!)

如果是这样,我不认为有任何东西MemberInfo,让你直接获得-你需要施法和使用MethodInfo.ReturnTypePropertyInfo.PropertyTypeFieldInfo.FieldTypeEventInfo.EventHandlerType和其他任何我忘了。(请记住,类型本身可以是成员。不确定你想用它们做什么!)

EDIT: If you're interested in whether a specific Type represents either MyType or some subclass, then use Type.IsAssignableFrom:

编辑:如果您对特定类型表示 MyType 还是某个子类感兴趣,请使用Type.IsAssignableFrom

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

EDIT: Now that we know you want properties, it's easy - use GetProperties instead of GetMembers. I like doing reflection with LINQ:

编辑:既然我们知道您想要属性,这很容易 - 使用 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);
}

If you're not a fan of LINQ:

如果您不是 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");

Note that you might want to specify binding flags to get non-public properties etc.

请注意,您可能希望指定绑定标志以获取非公共属性等。

回答by Paolo Tedesco

I think you need something like this:

我认为你需要这样的东西:

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;
    }
}

回答by Alexander

You are looking for:

您正在寻找:

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

right ?

对 ?

回答by rivy

There are multiple ways to test an object's type:

有多种方法可以测试对象的类型:

1) Use the isoperator:

1) 使用is运算符:

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

2) Use the asoperator:

2) 使用as运算符:

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

3) Use typeof() and GetType() [3 variations]:

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

回答by BFree

Ok, maybe I'm missing something stupid, but shouldn't it be:

好吧,也许我错过了一些愚蠢的东西,但不应该是:

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

???

???

回答by vlr

This example from the other similar question simplified the understanding for me a lot

这个来自其他类似问题的例子大大简化了我的理解

If p.PropertyType Is GetType(String) Then

If p.PropertyType Is GetType(String) Then

回答by PeteGO

You should use iswhen comparing an instance of something with an explicitly written type:

is在将某事物的实例与显式编写的类型进行比较时,您应该使用:

Department sales = new Department("Sales");

Debug.Assert(sales is Department);

You should use typeof when you want to compare 2 types and you can't write the type explicitly:

当您想比较 2 种类型并且不能显式编写类型时,您应该使用 typeof:

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

Using iswill take inheritence into account, typeofwont.

使用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
}

If you want to compare 2 types and take inheritence into account, you can use IsAssignableFrom:

如果要比较 2 种类型并考虑继承,可以使用IsAssignableFrom

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

回答by Sabarinathan Arthanari

This is shortcut way

这是捷径

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