Intento saber si existe una propiedad en una clase, probé esto:
public static bool HasProperty(this object obj, string propertyName)
{
return obj.GetType().GetProperty(propertyName) != null;
}
No entiendo por qué no pasa el primer método de prueba.
[TestMethod]
public void Test_HasProperty_True()
{
var res = typeof(MyClass).HasProperty("Label");
Assert.IsTrue(res);
}
[TestMethod]
public void Test_HasProperty_False()
{
var res = typeof(MyClass).HasProperty("Lab");
Assert.IsFalse(res);
}
c#
.net
reflection
Kris-I
fuente
fuente
MyClass
?Respuestas:
Tu método se ve así:
public static bool HasProperty(this object obj, string propertyName) { return obj.GetType().GetProperty(propertyName) != null; }
Esto agrega una extensión a
object
la clase base de todo . Cuando llama a esta extensión, le está pasando unType
:var res = typeof(MyClass).HasProperty("Label");
Su método espera una instancia de una clase, no un
Type
. De lo contrario, esencialmente estás haciendotypeof(MyClass) - this gives an instanceof `System.Type`.
Entonces
type.GetType() - this gives `System.Type` Getproperty('xxx') - whatever you provide as xxx is unlikely to be on `System.Type`
Como @PeterRitchie señala correctamente, en este punto su código está buscando una propiedad
Label
enSystem.Type
. Esa propiedad no existe.La solución es
a) Proporcione una instancia de MyClass a la extensión:
var myInstance = new MyClass() myInstance.HasProperty("Label")
b) Pon la extensión en
System.Type
public static bool HasProperty(this Type obj, string propertyName) { return obj.GetProperty(propertyName) != null; }
y
typeof(MyClass).HasProperty("Label");
fuente
, not
MyClass.Label`.Esto responde a una pregunta diferente:
Si está tratando de averiguar si un OBJETO (no una clase) tiene una propiedad,
OBJECT.GetType().GetProperty("PROPERTY") != null
devuelve verdadero si (pero no solo si) la propiedad existe.
En mi caso, estaba en una vista parcial ASP.NET MVC y quería renderizar algo si la propiedad no existía o la propiedad (booleana) era verdadera.
@if ((Model.GetType().GetProperty("AddTimeoffBlackouts") == null) || Model.AddTimeoffBlackouts)
me ayudó aquí.
Editar: hoy en día, probablemente sea inteligente usar el
nameof
operador en lugar del nombre de propiedad en cadena.fuente
nameof
operador, ¿funcionará (sin lanzar una excepción) para obtener el nombre de una propiedad que puede no existir? ¿Dado que la premisa de la pregunta original era que no sabemos si existe esta propiedad?Hay 2 posibilidades.
Realmente no tienes
Label
propiedad.Debe llamar a la sobrecarga de GetProperty apropiada y pasar las banderas de enlace correctas, por ejemplo
BindingFlags.Public | BindingFlags.Instance
Si su propiedad no es pública, deberá usar
BindingFlags.NonPublic
o alguna otra combinación de indicadores que se adapte a su caso de uso. Lea los documentos de la API a los que se hace referencia para encontrar los detalles.EDITAR:
Lamentablemente, solo se dio cuenta de que llame
GetProperty
atypeof(MyClass)
.typeof(MyClass)
es elType
que seguro no tieneLabel
propiedad.fuente
Instance|Public|Static
iirc.Label
sea propiedad privada.Recibí este error: "El tipo no contiene una definición para GetProperty" al vincular la respuesta aceptada.
Esto es con lo que terminé:
using System.Reflection; if (productModel.GetType().GetTypeInfo().GetDeclaredProperty(propertyName) != null) { }
fuente
Si estás vinculante como yo:
<%# Container.DataItem.GetType().GetProperty("Property1") != null ? DataBinder.Eval(Container.DataItem, "Property1") : DataBinder.Eval(Container.DataItem, "Property2") %>
fuente
No estoy seguro del contexto de por qué era necesario, por lo que es posible que esto no le devuelva suficiente información, pero esto es lo que pude hacer:
if(typeof(ModelName).GetProperty("Name of Property") != null) { //whatevver you were wanting to do. }
En mi caso, estoy revisando las propiedades de un envío de formulario y también tengo valores predeterminados para usar si la entrada se deja en blanco, por lo que necesitaba saber si había un valor para usar, prefijé todos mis valores predeterminados en el modelo con Default, así que todo lo que tenía que hacer era verificar si había una propiedad que comenzara con eso.
fuente