views:

1349

answers:

5

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).

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

+11  A: 

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 MemberInfo to let you get at it directly - you'll need to cast and use MethodInfo.ReturnType, PropertyInfo.PropertyType, FieldInfo.FieldType, EventInfo.EventHandlerType and any others I've forgotten. (Remember that types themselves can be members. Not sure what you'll want to do with them!)

EDIT: If you're interested in whether a specific Type represents either MyType or some subclass, then use 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:

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:

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.

Jon Skeet
I should have said "properties" instead of "members". I've updated the question, hopefully it's clearer now.
Ed Guiness
@Jon Skeet: unrelated: have you seen the FinalBuilder Advert? Quite funny!
Mitch Wheat
@Mitch: Yup. They asked me very nicely whether it was okay first, too.
Jon Skeet
+1  A: 

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;
    }
}
Paolo Tedesco
The warning I get is CS0184: The given expression is never of the provided type
Ed Guiness
That's because its type is System.Type... check my code, hope it helps.
Paolo Tedesco
+1  A: 

You are looking for:

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

right ?

Alexander
+1  A: 

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

1) Use the is operator:

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

2) Use the as operator:

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

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

// #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);
}
Roy
A: 

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

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

???

BFree