¿Es posible? Con reflexión o de otra manera?Cambio de propiedades de solo lectura con reflexión
Respuesta
Como dice otro, si necesita hacer eso, se enfrenta a un problema de diseño para empezar. Ahora, si quiere saber si es posible por el solo hecho de saberlo, o si no hay otra manera en la tierra para hacerlo, de hecho es posible, con la ayuda de un muy pequeño helper library y un método de extensión.
Considere el siguiente código:
class Person {
int age;
string name;
public int Age { get { return age; } }
public string Name { get { return name; } }
}
// ...
using Mono.Reflection;
using System.Reflection;
// ...
Person person = new Person (27, "jb");
PropertyInfo nameProperty = typeof (Person).GetProperty ("Name");
FieldInfo nameField = nameProperty.GetBackingField();
nameField.SetValue (person, "jbe");
Usando este código, se puede obtener el respaldo de campo de una propiedad con sólo la propiedad, y asignar un nuevo valor al campo de respaldo. Puede leer más detalles sobre implementation.
También tenga en cuenta que sólo funciona para las propiedades simples, tales como:
public int Age { get { return age; } }
public string Name {
get { return name; }
set { name = value; }
}
public double Velocity { get; private set; }
Si tiene propiedades complejas con código personalizado, el sistema de resolución de campo respaldo fallará.
depende de la propiedad. si se trata de una propiedad calculada, no, a menos que sepa en qué se basa. si solo es un acceso a un campo privado, entonces puede intentar modificar el campo.
en general, sin embargo, es una muy mala idea, ya que es probable que no tenga conocimiento de los efectos secundarios que esto ocasionará.
PropertyInfo isReadOnly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance| BindingFlags.NonPublic);
//Remove the readonly property
isReadOnly.SetValue(param, false, null);
//.............put your code here.....
// Set readonly property
isReadOnly.SetValue(param, true, null);
Como una solución muy sucio para auto genera sólo lectura propiedades:
class MyTestClass
{
public string MyProperty { get; }
public MyTestClass(string MyProperty)
{
this.MyProperty = MyProperty;
}
}
Puede modificar el automático genera el campo respaldo de la siguiente manera:
MyTestClass MyClass = new MyTestClass("Hello");
FieldInfo MyWriteableField = MyClass.GetType().GetRuntimeFields().Where(a => Regex.IsMatch(a.Name, $"\\A<{nameof(MyClass.MyProperty)}>k__BackingField\\Z")).FirstOrDefault();
MyWriteableField.SetValue(MyClass, "Another new value");
PD: cuando están utilizando una .NET versión < 4.6 es posible que tenga que cambiar parte del código para que funcione. ¡Disfrútalo!
Una alternativa a la respuesta Simon Mattes sería
Suponiendo que tienen:
public class MyClass
{
public int MyNumber {get;}
}
Usted puede hacer esto si es para el propósito de la prueba:
var field = typeof(MyClass).GetField("<MyNumber>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(anIstanceOfMyClass, 3);
- 1. TwoWay MultiBinding con propiedades de solo lectura
- 2. WCF DataContract con propiedades de solo lectura
- 3. propiedades de solo lectura en PHP?
- 4. Propiedades de solo lectura en EF 4.1
- 5. Impulsar propiedades de GUI de solo lectura en ViewModel
- 6. Propiedades de solo lectura de nivel de clase en Python
- 7. WCF DataContract serialización de propiedades de solo lectura?
- 8. Definición de propiedades de solo lectura en JavaScript
- 9. C# propiedades de solo lectura calculadas, ¿deberían ser métodos?
- 10. ¿Por qué las propiedades no pueden ser de solo lectura?
- 11. WPF INotifyPropertyChanged para propiedades de solo lectura vinculadas
- 12. Json.NET Serializar miembros privados y no propiedades de solo lectura
- 13. Obtener todas las propiedades con los valores de reflexión
- 14. Lectura de propiedades de tomcat
- 15. C# - Valores de propiedades recursivas/de reflexión
- 16. Rendimiento de reflexión - Crear delegado (Propiedades C#)
- 17. ¿Esto no acaba con el propósito de tener propiedades de solo lectura?
- 18. Establecer las propiedades de un objeto a través de la reflexión con diferentes propiedades tipos
- 19. Hacer una rama TFS de solo lectura
- 20. SQLite/PHP de solo lectura?
- 21. ¿navegador independiente de solo lectura?
- 22. ¿Puedo cambiar un campo heredado de solo lectura privado en C# usando reflexión?
- 23. Obtener propiedades de lectura/escritura de tipo anónimo
- 24. SVN: ¿Cómo hacer un archivo de solo lectura con subversión?
- 25. Solo lectura DB Connection Strings
- 26. Uso de las propiedades de lectura de reflexión de un objeto que contiene una matriz de otro objeto
- 27. Abrir archivo de solo lectura
- 28. Propiedades de cambio de nombre de Json.net
- 29. Resultados de reflexión de caché (propiedades de clase)
- 30. Cocoa NSView cambio de propiedades de autosizing
Élodie: Es posible, pero * * ¡NO LO HAGAS **! – Gabe
¿Está tratando de cambiar el valor de retorno de una propiedad con getter solamente, o el valor de un campo de respaldo que es de solo lectura (como 'private readonly int primitiveValue = 1;')? – Elisha
Hola Élodie, ¿podrías solicitar más información o aceptar una respuesta? –