C# Unproven确保结合接口引用另一个属性
假设以下代码:C# Unproven确保结合接口引用另一个属性,c#,.net,code-contracts,C#,.net,Code Contracts,假设以下代码: [ContractClass(typeof(ICC4Contract))] public interface ICC4 { bool IsFooSet { get; } string Foo { get; } } public class CC4 : ICC4 { private string _foo; public bool IsFooSet { get { return Foo != null; } } public strin
[ContractClass(typeof(ICC4Contract))]
public interface ICC4
{
bool IsFooSet { get; }
string Foo { get; }
}
public class CC4 : ICC4
{
private string _foo;
public bool IsFooSet { get { return Foo != null; } }
public string Foo { get { return _foo; } }
}
[ContractClassFor(typeof(ICC4))]
public abstract class ICC4Contract : ICC4
{
public bool IsFooSet
{
get
{
Contract.Ensures((Contract.Result<bool>() && Foo != null)
|| !Contract.Result<bool>());
return false;
}
}
public string Foo
{
get
{
Contract.Ensures((Contract.Result<string>() != null && IsFooSet)
|| !IsFooSet);
return null;
}
}
}
[ContractClass(类型(ICC4Contract))]
公共接口ICC4
{
bool-IsFooSet{get;}
字符串Foo{get;}
}
公共类CC4:ICC4
{
私人字符串(u foo),;
公共bool IsFooSet{get{return Foo!=null;}}
公共字符串Foo{get{return\u Foo;}}
}
[合同类别(类型(ICC4))]
公共抽象类ICC4Contract:ICC4
{
公共bool-IsFooSet
{
得到
{
Contract.surveures((Contract.Result()&&Foo!=null)
||!Contract.Result());
返回false;
}
}
公共字符串Foo
{
得到
{
Contract.surveures((Contract.Result()!=null&&IsFooSet)
||!IsFooSet);
返回null;
}
}
}
合同试图说明:
Foo
不是null
,则IsFooSet
将返回true
Foo
不返回null
如果IsFooSet
返回true
然而,我在
return\u foo
,因为检查器没有意识到Foo
始终等于\u Foo
将Foo
更改为带有private
setter的自动属性会删除该警告,但我不想这样做(我不喜欢带有private setter的自动属性)
在保留\u foo
字段的同时,我必须对上述代码进行哪些更改才能使警告消失?
以下操作不起作用:
IsFooSet
更改为使用\u foo
而不是foo
。这将导致IsFooSet
上出现额外的“未经验证”Foo==\u Foo
。这将导致隐式默认构造函数出现“未经验证的不变”。此外,在实际代码基础上,静态检查器的处理时间将更高Contract.sure(Contract.Result()==\u foo)
到Foo
的getter,按照不会改变任何内容您可以使用短路来简化条件,这是出于某些原因:
[ContractClassFor(typeof(ICC4))]
public abstract class ICC4Contract : ICC4
{
public bool IsFooSet
{
get
{
Contract.Ensures(!Contract.Result<bool>() || Foo != null);
return false;
}
}
public string Foo
{
get
{
Contract.Ensures(!IsFooSet || Contract.Result<string>() != null);
return null;
}
}
}
[ContractClassFor(typeof(ICC4))]
公共抽象类ICC4Contract:ICC4
{
公共bool-IsFooSet
{
得到
{
Contract.Result(!Contract.Result()| | Foo!=null);
返回false;
}
}
公共字符串Foo
{
得到
{
Contract.Contract(!IsFooSet | | Contract.Result()!=null);
返回null;
}
}
}
这对您的问题没有帮助,但我可以问您为什么不喜欢带有私有setter的自动属性吗?大多数情况下,这些属性都是类的不变量,也就是说,支持字段应设置为只读。对于自动属性,这是不可能的。实际上,我试图完全避免自动属性。原因如下。如果默认情况下将\u foo
设置为空字符串,是否会将其删除?感觉问题更多的是\u foo
的默认值将是null
@MichaelPerrenoud:不,这不会改变任何东西。为什么要这样做?\u foo
的默认值对已定义的契约没有影响。@DanielHilgarth,我当时的假设是编译器将拥有的唯一现实是违反契约的默认值\u foo
。