Utilización de las interfaces explícitas para evitar la modificación accidental de propiedades en C #

StackOverflow https://stackoverflow.com/questions/1717563

  •  19-09-2019
  •  | 
  •  

Pregunta

Me encontré con una característica de C # resolución método que no me di cuenta antes. A saber, cuando explícitamente implementar una interfaz que soporta un setter, y la interfaz implícita sólo ofrece un conjunto protegido, el compilador difiere sensiblemente al conjunto protegido cuando lo llamo. Por lo que obtener la mayor parte de la conveniencia de propiedades de auto-aplicado, pero no puedo evitar la modificación accidental de los campos por los clientes que no se debe cambiarlas.

Como ejemplo,

 virtual public DateTime CreatedOn { get; protected set; }
 virtual public DateTime? ModifiedOn { get; protected set; }
 #region IHaveUpdateDateFields Members

 DateTime IHaveUpdateDateFields.CreatedOn
 {
    get
    {
        return this.CreatedOn;
    }
    set
    {
        this.CreatedOn = value;
    }
}

DateTime? IHaveUpdateDateFields.ModifiedOn
{
    get
    {
        return this.ModifiedOn;
    }
    set
    {
        this.ModifiedOn = value;
    }
}

A continuación, mi modelo de código de enlace no se pone accidentalmente la fecha, pero mi ORM detector de eventos puede comprobar si hay entidades que implementan IHaveUpdateDateFields y establecer la fecha en que la persistencia de mi entidad.

Mis preguntas son:

  1. estoy confiando en el comportamiento definido, o estoy garantizado que todos los compiladores de C # resolverán los métodos de esta manera? No quiero descubrir que el C # norma dice que este tipo de método de resolución es indefinido y luego llegar accidentalmente a un desbordamiento de pila horrible cuando construyo para Mono, por ejemplo.
  2. ¿Hay una manera más agradable (lo ideal es más concisa) para hacer esto? Podría tener una interfaz ModelBinder de fallas que me pase a mi controlador, pero que no parece como que me ahorraría código y no creo que proporcionaría un enfoque lo más transparente de reducir al mínimo la modificación accidental de propiedades.
¿Fue útil?

Solución

Eso está perfectamente bien definido; las implementaciones de interfaces explícitas tienen prioridad cuando se utiliza la interfaz, y la propiedad normal entra en vigor de otro modo (incluso desde dentro del cuerpo de la get / set).

En cuanto a lo que es más ordenado ... lo mejor que puedo ofrecer es volver a formatear para que sea menos detallado ...

DateTime IHaveUpdateDateFields.CreatedOn
{
    get { return CreatedOn; }
    set { CreatedOn = value; }
}

(nota también que la this es implícito y redundante)

Como acotación al margen - la seguridad es sólo una conveniencia, no una garantía ... llamantes externos pueden todavía utilizar su interfaz, y pueden por lo general (ab) utilizar la reflexión para saltar meras cosas del pasado, como protected - o incluso sólo definir los campos directamente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top