web-dev-qa-db-ja.com

リフレクションを使用してプロパティタイプを決定するにはどうすればよいですか?

型のプロパティをテストして、指定された型であるかどうかを確認するにはどうすればよいですか?

編集:私の目標は、アセンブリを調べて、そのアセンブリのいずれかのタイプに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')タイプではありません

35
Ed Guiness

どのタイプに興味がありますか?メソッド/プロパティ/イベントなどの戻り値の型?

その場合、MemberInfoに直接アクセスできるものはないと思います-キャストして使用する必要がありますMethodInfo.ReturnTypePropertyInfo.PropertyTypeFieldInfo.FieldTypeEventInfo.EventHandlerTypeおよび私が忘れてしまった他のすべて。 (型自体がメンバーになる可能性があることを覚えておいてください。それらを使用して何をしたいのかわかりません!)

編集:特定のTypeがMyTypeまたはサブクラスのどちらを表すかを知りたい場合は、 Type.IsAssignableFrom を使用します。

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

編集:プロパティが必要なことがわかったので、簡単です-GetMembersの代わりにGetPropertiesを使用します。私は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");

非パブリックプロパティなどを取得するためにバインディングフラグを指定する場合があることに注意してください。

57
Jon Skeet

わかりました、たぶん私は何か愚かなものを見逃していますが、そうではないはずです:

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

???

48
BFree

オブジェクトのタイプをテストするには、複数の方法があります。

1)is演算子を使用します:

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

2)as演算子を使用します。

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

他の同様の質問からのこの例は、私にとって理解を非常に単純化しました

If p.PropertyType Is GetType(String) Then

1
vlr

次のようなものが必要だと思います。

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

あなたは探している:

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

正しい ?

1
Alexander

これは近道です

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

何かのインスタンスを明示的に記述された型と比較するときは、isを使用する必要があります。

Department sales = new Department("Sales");

Debug.Assert(sales is Department);

2つのタイプを比較する場合、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
}

2つのタイプを比較し、継承を考慮したい場合は、IsAssignableFromを使用できます。

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