Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用反射确定属性类型?_C#_.net_Reflection - Fatal编程技术网

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

C# 如何使用反射确定属性类型?,c#,.net,reflection,C#,.net,Reflection,如何测试类型的属性以确定它是否为指定类型 编辑:我的目标是检查程序集中的任何类型是否包含MyType属性(或从MyType继承的属性) 这是我走过的轨迹 AssemblyName n = new AssemblyName(); n.CodeBase = "file://" + dllName; Assembly a = AppDomain.CurrentDomain.Load(n); foreach (Type t in a.GetTypes()) foreach (PropertyI

如何测试类型的属性以确定它是否为指定类型

编辑:我的目标是检查程序集中的任何类型是否包含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')类型

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

如果是这样的话,我认为在
MemberInfo
中没有任何东西可以让您直接获得它-您需要强制转换并使用
MethodInfo.ReturnType
PropertyInfo.PropertyType
FieldInfo.FieldType
EventInfo.EventHandlerType
,以及我忘记的任何其他内容。(请记住,类型本身可以是成员。不确定您要如何处理它们!)

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

编辑:既然我们知道您想要属性,那么使用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");

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

我认为您需要这样的内容:

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;
    }
}
您正在寻找:

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

对吗?

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

1) 使用is操作符:

if (anObject is MyType) {
// anObject is MyType or a derived class
... 
}
MyType newObject = anObject as MyType;
if (newObject != null ) {
// newObject is anObject cast to MyType
...
}
2) 使用as操作符:

if (anObject is MyType) {
// anObject is MyType or a derived class
... 
}
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);
}

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

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

另一个类似问题的例子大大简化了我的理解


如果p.PropertyType是GetType(String),那么在比较某个实例与显式编写的类型时,应使用
Is

Department sales = new Department("Sales");

Debug.Assert(sales is Department);
如果要比较两种类型,但无法显式写入类型,则应使用typeof:

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
}
如果要比较两种类型并考虑继承性,可以使用
IsAssignableFrom

Debug.Assert(typeof(Animal).IsAssignableFrom(typeof(Dog))); // true
这是一条捷径

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

我应该说“属性”而不是“成员”。我已经更新了这个问题,希望现在更清楚了。@Jon Skeet:无关:你看过FinalBuilder的广告了吗?真有趣@米奇:是的。他们很友好地问了我是否还可以。我得到的警告是CS0184:给定的表达式永远不是提供的类型,因为它的类型是System.type。。。检查我的代码,希望它有帮助。这不会起作用,因为typeof(mi)的类型是Type,而不是mytypes,如果您的类型是泛型的(例如DbSet),您可以试试这个。。如果(pi.PropertyType.IsGenericType&&pi.PropertyType.GetGenericTypeDefinition()==typeof(DbSet)){…}这比接受的答案更有意义。IsAssignableFrom()看起来(我自己还没有测试过)如果该类型继承自另一个基类或接口,那么它可能与另一个类型匹配。例如:列表可以从IEnumerable和viceversa中识别。