c# - what - ¿Es posible obtener un setter privado de una propiedad a través de la reflexión?
what can be done with reflection in c# (1)
Como ya descubrió, una forma de acceder a un configurador no público es la siguiente:
PropertyInfo property = typeof(Type).GetProperty("Property");
property.DeclaringType.GetProperty("Property");
property.GetSetMethod(true).Invoke(obj, new object[] { value });
Hay otra manera, sin embargo:
PropertyInfo property = typeof(Type).GetProperty("Property");
property.DeclaringType.GetProperty("Property");
property.SetValue(obj, value, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null); // If the setter might be public, add the BindingFlags.Public flag.
¿Viene aquí de un motor de búsqueda?
Esta pregunta es específicamente acerca del acceso a un colocador no público en una propiedad pública .
- Si tanto la propiedad como el establecedor son públicos, solo el primer ejemplo funcionará para usted. Para que el segundo ejemplo funcione, deberá agregar la
BindingFlags.Public
. - Si la propiedad se declara en un tipo principal y no es visible para el tipo al que llama
GetProperty
, no podrá acceder a ella. Deberá llamar aGetProperty
en un tipo en el que la propiedad esté visible. (Esto no afecta a los establecedores privados siempre que la propiedad sea visible). - Si hay varias declaraciones para la misma propiedad en la cadena de herencia (a través de la
new
palabra clave), estos ejemplos apuntarán a la propiedad que es inmediatamente visible para el tipo en el que se llamaGetProperty
. Por ejemplo, si la clase A declara propiedad usandopublic int Property
, y la clase B re-declara propiedad a través depublic new int Property
,typeof(B).GetProperty("Property")
devolverá la propiedad declarada en B, mientras quetypeof(A).GetProperty("Property")
devolverá la propiedad declarada en A.
Escribí un serializador personalizado que funciona configurando las propiedades del objeto por reflexión. Las clases serializables están etiquetadas con un atributo serializable y todas las propiedades serializables también están etiquetadas. Por ejemplo, la siguiente clase es serializable:
[Serializable]
public class Foo
{
[SerializableProperty]
public string SomethingSerializable {get; set;}
public string SometthingNotSerializable {get; set;}
}
Cuando se le pide al serializador que deserialice SomethingSerializable
, obtiene el método set de la propiedad y lo usa para configurarlo haciendo algo como esto:
PropertyInfo propertyInfo; //the property info of the property to set
//...//
if (propertyInfo.CanWrite && propertyInfo.GetSetMethod() != null)
{
propertyInfo.GetSetMethod().Invoke(obj, new object[]{val});
}
Esto funciona bien, sin embargo, ¿cómo puedo hacer que el configurador de propiedades sea accesible solo para el serializador? Si el setter es privado:
public string SomethingSerializable {get; private set;}
entonces la llamada a propertyInfo.GetSetMethod()
devuelve un valor nulo en el serializador. ¿Hay alguna forma de acceder al setter privado o de otra manera para asegurar que solo el serializador pueda acceder al setter? No se garantiza que el serializador esté en el mismo ensamblaje.