¿Cómo puedo probar una propiedad de un tipo para ver si se trata de un tipo especificado?

EDIT: Mi objetivo es examinar una asamblea para ver si alguno de los tipos en que la asamblea contienen propiedades que están MyType (o heredado de MyType).

Aquí es el track que he bajado…

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

Esto compila con la advertencia CS0184: La expresión dada no es de los de siempre (‘MyType’) tipo de

InformationsquelleAutor Ed Guiness | 2009-02-06

8 Comentarios

  1. 58

    De qué tipo son los que te interesan? El tipo de retorno del método/propiedad/evento etc?

    Si es así, yo no creo que haya nada en MemberInfo de hacerle llegar a él directamente, tendrás que convertir y usar MethodInfo.ReturnType, PropertyInfo.PropertyType, FieldInfo.FieldType, EventInfo.EventHandlerType y cualesquiera otros que se me ha olvidado. (Recuerde que los tipos pueden ser miembros. No sabes lo que quieres hacer con ellos!)

    EDIT: Si usted está interesado en un Tipo específico representa MyType o alguna subclase, a continuación, utilizar Tipo.IsAssignableFrom:

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

    EDIT: Ahora que sabemos que usted quiere propiedades, es fácil de usar GetProperties en lugar de GetMembers. Me gusta hacer la reflexión con 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);
    }

    Si no eres un fan de 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");

    Tenga en cuenta que es posible que desee especificar unión de las banderas para obtener la no-pública de propiedades etc.

    • Debería haber dicho «propiedades» en lugar de «miembros». He actualizado a la pregunta, esperamos que sea más claro ahora.
    • Skeet: relacionado: ¿has visto la FinalBuilder Anuncio? Muy divertido!
    • Yup. Me preguntaron muy bien si estaba bien la primera, demasiado.
  2. 48

    Ok, tal vez me estoy perdiendo algo estúpido, pero ¿no debería ser:

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

    ???

    • Y si el tipo es genérico (por ejemplo. DbSet<>) usted puede tratar de esta.. si (pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)) { … }
    • Esto tiene más sentido que el aceptado respuesta. tipo.IsAssignableFrom() parece (yo no lo he probado yo mismo) podría coincidir con otro tipo, si el tipo se hereda de otra clase base o de la interfaz. Por ejemplo: una Lista de<T> podría ser IsAssignableFrom IEnumerable<T> y viceversa.
  3. 2

    Hay varias formas de probar un tipo de objeto:

    1) el Uso de la es operador:

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

    2) el Uso de la como operador:

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

    3) Uso typeof() y GetType() [3 variaciones]:

    //#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);
    }
  4. 1

    Usted está buscando:

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

    derecho ?

    • Esto no va a funcionar, como el Tipo de typeof(mi) es el Tipo, no MyType
  5. 1

    Creo que necesitas algo como esto:

    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;
        }
    }
    • La advertencia que tengo es CS0184: La expresión dada no es de el tipo de
    • Eso es porque su tipo de Sistema.Tipo de… revisar mi código, espero que ayude.
  6. 1

    Este ejemplo de la otra pregunta similar simplificado el entendimiento mucho para mí

    If p.PropertyType Is GetType(String) Then

  7. 0

    Debe utilizar is cuando se compara una instancia de algo con un explícitamente escrito tipo:

    Department sales = new Department("Sales");
    
    Debug.Assert(sales is Department);

    Debe utilizar typeof cuando se desea comparar los 2 tipos y usted no puede escribir explícitamente el tipo:

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

    Utilizando is tendrá inheritence en cuenta, typeof no.

    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
    }

    Si quieres comparar 2 tipos y tomar inheritence en cuenta, puede utilizar IsAssignableFrom:

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

    Este es un atajo manera

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

Dejar respuesta

Please enter your comment!
Please enter your name here