Utilizando as Interfaces explícitas para impedir a modificação acidental de propriedades em C #

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

  •  19-09-2019
  •  | 
  •  

Pergunta

Eu tropecei em um recurso de resolução # método C que eu não percebi antes. Ou seja, quando eu explicitamente implementar uma interface que suporta um setter, ea interface implícito só oferece um conjunto protegido, o compilador sensatamente remete para o conjunto protegido quando eu chamá-lo. Então eu fico a maior parte da conveniência de propriedades implementadas automaticamente, mas posso impedir a modificação acidental de campos por clientes que não deve ser alterá-los.

Como exemplo,

 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;
    }
}

Então meu modelo de código ligação não acidentalmente definir a data, mas meu ORM evento ouvinte pode verificar a existência de entidades que implementam IHaveUpdateDateFields e definir a data em que persiste a minha entidade.

As minhas perguntas são:

  1. Am I contando com comportamento definido, ou estou garantido que todos C # compiladores irá resolver métodos desta maneira? Eu não quero para descobrir que o C # padrão diz que este tipo de resolução método é indefinido e, em seguida, acidentalmente obter um estouro de pilha horrível quando eu construir para Mono, por exemplo.
  2. Existe uma agradável (idealmente terser) maneira de fazer isso? Eu poderia ter uma interface ModelBinder-safe que eu passar para o meu controlador, mas isso não parece que ele iria me salvar código e eu não acho que isso iria fornecer o mais transparente uma abordagem de minimizar modificação acidental de propriedades.
Foi útil?

Solução

Isso é perfeitamente bem definida; as implementações de interfaces explícitas têm prioridade quando se utiliza a interface, ea propriedade regular leva efeito de outra forma (incluindo de dentro do corpo do get / set).

Como para torná-lo mais arrumado ... o melhor que posso oferecer é reformatá-lo para torná-lo menos extenso ...

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

(note-se também que o this é implícita e redundante)

Como um aparte - a segurança é apenas uma conveniência, e não uma garantia ... chamadores externos ainda pode usar o seu interface, e geralmente pode (ab) uso de reflexão para saltar últimos meras coisas como protected - ou mesmo apenas definir os campos diretamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top