Quando usar o [Pure] em um construtor?

15

Estou aprendendo sobre contratos de código no .NET e estou tentando entender a ideia de construtores puros. Os estados da documentação contratos de código :

All methods that are called within a contract must be pure; that is, they must not update any preexisting state. A pure method is allowed to modify objects that have been created after entry into the pure method.

E o PureAttribute documentação afirma:

Indicates that a type or method is pure, that is, it does not make any visible state changes.

Eu entendo essas declarações quando se trata de métodos, mas e construtores? Suponha que você tenha uma aula assim:

public class Foo
{
    public int Value { get; set; }

    public Foo(int value) {
        this.Value = value;
    }
}

Este construtor obviamente afeta o estado do novo objeto Foo , mas não tem outros efeitos colaterais (por exemplo, ele não manipula nenhum dos parâmetros ou chama qualquer método não-puro). Isso é um candidato para [Pure] ou não? Qual é o significado de colocar um atributo [Pure] em um construtor e quando devo fazer isso em meu próprio código?

    
por p.s.w.g 01.07.2014 / 18:20
fonte

2 respostas

11

Você decorar um método com [Pure] :

  • Se o método não tiver efeitos colaterais. Por exemplo, se o método acessa um banco de dados e o modifica ou seu resultado depende do banco de dados, não é puro.

  • E se você espera usá-lo em contratos de código. Por exemplo, se o método é puro , mas você não tem intenção de usá-lo em contratos de código, adicionar [Pure] não teria nenhum benefício e não tornaria seu código mais rápido.

No que diz respeito aos construtores, parece que eles são assumidos como puros no .NET e não precisam de um atributo explícito. Eu olhei vários construtores na fonte do .NET Framework, como DateTime , e eles não têm [Pure] attribute.

Suponho que isso seja feito por vários motivos:

  • Pode ser muito impraticável ter que escrever um construtor sem parâmetros com o atributo [Pure] apenas para poder usar a classe / estrutura em um contrato.

  • Alguns, como String , não têm construtores explícitos.

  • Os construtores recebem tratamento especial mesmo fora dos contratos de código; por exemplo, você não deve lançar exceções dentro deles .

  • [Pure] é apenas uma convenção que está aqui para simplificar sua vida, mas não há verificação estática real para garantir que o método decorado com esse atributo seja puro. void DestroyDatabase() pode ser decorado como puro e os contratos de código não notarão nada de errado.

    Currently there is no component of Code Contracts which checks if methods declared pure are pure indeed. Thus if a programmer decorated a method with [Pure], it’s just believed.

    From Code Contracts #5: Method purity

  • O próprio .NET Framework contém construtores que não são puros. Por exemplo, List<T>(IEnumerable<T> collection) é realmente impuro se o loop através da coleção efeitos colaterais.

  • Os contratos gritam ser mantidos simples. Eu posso facilmente imaginar um contrato como Contract.Requires(!string.IsNullOrEmpty(name)) , então há boas razões para declarar a estática string.IsNullOrEmpty pure.

    Por outro lado, se você precisar de um StringBuilder para criar a string, você verificará, em seguida, algo chamando um método de instância de sua classe de negócios, provavelmente você está usando indevidamente os contratos. É também por isso que StringBuilder.ToString não está marcado como puro, mesmo que possa ser (é isso?)

por 01.07.2014 / 18:52
fonte
1

O objeto não pode ser usado até que seja construído neste caso. Portanto, o construtor é puro. Se o construtor chamou outro código ou invocou um delegado, e o outro modificou a propriedade mutável, ele não seria puro. Para ser mais seguro, é melhor tornar a propriedade imutável.

    
por 01.07.2014 / 18:26
fonte