Reputation: 35287
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
Upvotes: 38
Views: 63146
Reputation: 1
This is shortcut way
property.PropertyType.IsGenericType && (typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition()))
&& typeof(<YourType>).IsAssignableFrom(property.PropertyType.GenericTypeArguments[0])
Upvotes: 0
Reputation: 5791
You should use is
when comparing an instance of something with an explicitly written type:
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:
private void CheckType(Type t)
{
Debug.Assert(typeof(Department) == t);
}
Using is
will take inheritence into account, 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
}
If you want to compare 2 types and take inheritence into account, you can use IsAssignableFrom
:
Debug.Assert(typeof(Animal).IsAssignableFrom(typeof(Dog))); // true
Upvotes: 0
Reputation: 790
This example from the other similar question simplified the understanding for me a lot
If p.PropertyType Is GetType(String) Then
Upvotes: 1
Reputation: 1630
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);
}
Upvotes: 2
Reputation: 57302
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;
}
}
Upvotes: 1
Reputation: 1504002
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.
Upvotes: 59
Reputation: 103770
Ok, maybe I'm missing something stupid, but shouldn't it be:
if ( pi.PropertyType == typeof(MyType ))
???
Upvotes: 48