2009-02-06 27 views
31

Jak przetestować właściwość typu, aby zobaczyć, czy jest to określony typ?Jak określić typy właściwości za pomocą odbicia?

EDYCJA: Moim celem jest zbadanie złożenia, aby zobaczyć, czy którykolwiek z typów w tym zestawie zawiera właściwości, które są MyType (lub odziedziczone z MyType).

Oto utwór Poszedłem na dół ...

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

To kompiluje z CS0184 UWAGA: podane wyrażenie jest nigdy z dostarczonym („”) MyType wpisać

Odpowiedz

54

Jakie są jesteś zainteresowany? Typ zwrotu metody/właściwości/zdarzenia itp.?

Jeśli tak, to nie sądzę, jest coś w MemberInfo aby uzyskać na nią bezpośrednio - musisz oddać i korzystać MethodInfo.ReturnType, PropertyInfo.PropertyType, FieldInfo.FieldType, EventInfo.EventHandlerType i wszelkich innych zapomniałem. (Pamiętaj, że same typy mogą być członkami.) Nie wiem, co chcesz z nimi zrobić!)

EDYCJA: Jeśli interesuje Cię, czy określony typ reprezentuje typ MyType, czy podklasę, użyj Type.IsAssignableFrom:

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

EDYCJA: Teraz wiemy, że chcesz właściwości, to proste - użyj GetProperties zamiast GetMembers. Lubię robić odbicia z 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); 
} 

Jeśli nie jesteś fanem 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"); 

Pamiętaj, że możesz określić wiążące flagi, aby uzyskać właściwości niepubliczne itp

+0

powinienem powiedzieć "Właściwości" zamiast "członków". Zaktualizowałem to pytanie, mam nadzieję, że teraz jest jaśniejsze. –

+0

@ Jon Skeet: nie związany: czy widziałeś ogłoszenie FinalBuilder? Całkiem śmieszne! –

+1

@Mitch: Yup. Bardzo spytali mnie, czy to też jest w porządku. –

1

myślę, że trzeba coś takiego:

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

Otrzymane ostrzeżenie to CS0184: Podane wyrażenie nigdy nie ma podanego typu. –

+0

To dlatego, że jego typ to System.Type ... sprawdź mój kod, mam nadzieję, że to pomaga. –

1

szukasz:

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

prawo?

+0

To nie zadziała, ponieważ Typ typeof (mi) to Type, a nie MyType – HAL9000

1

Istnieje wiele sposobów na test typu obiektu,:

1) obsługi jest operatora:

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

2) Za pomocą jako operatora:

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

3) Użyj typeof() i GetType() [3 warianty]:

// #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); 
} 
43

Ok, może brakuje mi coś głupiego, ale nie powinno to być:

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

???

+0

Dodaj, dziękuję za dodanie. –

+0

Dziękuję za to rozwiązanie! – grmbl

+1

A jeśli Twój typ jest ogólny (np. DbSet <>), możesz spróbować tego .. if (pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition() == typeof (DbSet <>)) { ... } – timothy

0

Ten przykład z innej podobnej pytanie uprościć zrozumienie dla mnie dużo

If p.PropertyType Is GetType(String) Then

0

należy użyć is przy porównywaniu wystąpienie coś z wyraźnie napisane typu:

Department sales = new Department("Sales"); 

Debug.Assert(sales is Department); 

Powinieneś używać typeof, aby porównać 2 typy i nie możesz bezpośrednio pisać typu:

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

Korzystanie z is bierze pod uwagę dziedziczenie, typeof wont.

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 
} 

Jeśli chcesz porównać 2 typy i wziąć Dziedziczenie pod uwagę, można użyć IsAssignableFrom:

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

Jest to skrót sposób

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