问题
Is there any way to put contracts on automatically implemented properties in .NET? (And how if the answer is 'Yes')?
(I assume using .NET code contracts from DevLabs)
回答1:
Yes, this is possible - all that is needed is to add your contract condition to the [ContractInvariantMethod]
method in your class, which then adds the equivalent Requires
precondition to the automatic set
ter, and a post condition Ensures
is added to the get
. From section 2.3.1 of the Reference
As the example illustrates, invariants on auto-properties turn into:
- A precondition for the setter
- A postcondition for the getter
- An invariant for the underlying backing field
And by example:
public int MyProperty { get; private set ;}
[ContractInvariantMethod]
private void ObjectInvariant ()
{
Contract.Invariant ( this.MyProperty >= 0 );
}
"Is equivalent to the following code:"
private int backingFieldForMyProperty;
public int MyProperty
{
get
{
Contract.Ensures(Contract.Result<int>() >= 0);
return this.backingFieldForMyProperty;
}
private set
{
Contract.Requires(value >= 0);
this.backingFieldForMyProperty = value;
}
}
[ContractInvariantMethod]
private void ObjectInvariant ()
{
Contract.Invariant ( this.backingFieldForMyProperty >= 0 );
...
回答2:
I'm thinking not, but you could easily write a snippet that would do this. If you go this route, here is a free snippet editor that will make the task very easy.
回答3:
Thanks Porges.
My mistake was that I actually used ReleaseRequires
option, which, indeed, deals only with generic version of the method, Requires<T>
.
Invariant which is put on an auto-implemented property is really turned into a Requires
precondition, but it's not generic - that's why it didn't work using this option.
What to do:
VARIANT 1. Consider using code snippets and lovely
Requires<T>
instead of auto-implemented properties - that enables us to use exceptions of desired type.VARIANT 2. Change the option
ReleaseRequires
toPreconditions
in the Code Contracts' options and feel free to write invariants on auto-properties - the rewriter tool will automatically change them into theRequires
. However, they will be non-generic - that means, in case of contract broken, aContractException
will be thrown and there is no way to change this behaviour.
Thanks everyone for the help!
来源:https://stackoverflow.com/questions/5513942/code-contracts-on-auto-implemented-properties