接口的 ContractInvariant 方法
ContractInvariant method for interface
我是合同新手 我浏览了代码合同的 msdn 文档
https://msdn.microsoft.com/en-us/library/dd264808(v=vs.110).aspx
我选择了契约不变量的想法。但是,当我添加不变方法时,它不会访问字段表单接口。
[ContractClass(typeof(Account_Contract))]
public interface IAccount
{
int AccountID { get; }
string AccountOwner { get; }
int GetAccountID(); // Our 'internal'unique identifier for this account
}
[ContractClassFor(typeof(IAccount))]
internal abstract class Account_Contract : IAccount
{
int IAccount.AccountID
{
get
{
Contract.Ensures(Contract.Result<int>() > 0);
return default(int);
}
}
string IAccount.AccountOwner
{
get
{
Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));
return default(string);
}
}
int IAccount.GetAccountID()
{
Contract.Ensures(Contract.Result<int>() > 0);
return default(int);
}
}
它工作正常,但如果我添加
Contracts.Requires(AccountID > 0);
VS 不访问它。我也试过
Contracts.Requires(this.AccountID > 0);
Contracts.Requires(IAccount.AccountID > 0);
None 正在工作。我哪里做错了。
你的问题是你正在使用显式声明(因为@Chris 在他的回答中有评论),所以你必须将 this
转换为 IAccount
.
我认为你应该使用隐式声明(常用),因为IAccount
实现的所有方法和道具必须public。
隐式声明方式:
[ContractClassFor(typeof(IAccount))]
internal abstract class Account_Contract : IAccount
{
//In order to implement IAccount interface, must be public
public int AccountID
{
get
{
Contract.Requires(AccountID > 0);
return default(int);
}
}
//In order to implement IAccount interface, must be public
public string AccountOwner
{
get
{
Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));
return default(string);
}
}
//In order to implement IAccount interface, must be public
public int GetAccountID()
{
Contract.Ensures(Contract.Result<int>() > 0);
return default(int);
}
}
[ContractClass(typeof(Account_Contract))]
public interface IAccount
{
int AccountID { get; }
string AccountOwner { get; }
int GetAccountID(); ////Our 'internal'unique identifier for this account
}
编辑:我在这里包括@Cris 的回答。
显式声明方式:
[ContractClassFor(typeof(IAccount))]
internal abstract class Account_Contract : IAccount
{
int IAccount.AccountID
{
get
{
//You must cast this as IAccount
Contract.Requires(((IAccount)this).AccountID > 0);
return default(int);
}
}
string IAccount.AccountOwner
{
get
{
Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));
return default(string);
}
}
public int GetAccountID()
{
Contract.Ensures(Contract.Result<int>() > 0);
return default(int);
}
}
您正在使用接口的显式实现,这意味着如果您想将对象视为该接口的成员,那么您需要先转换为该接口。
因此,当您想要访问名为 myInstance
的实例上的 AccountID
时,您需要编写 ((IAccount)myInstance).AccountId
。如果您尝试直接在 class 上访问 AccountId
,那么它不会被识别。
这意味着如果您需要从 class 中为您的合约引用它,您应该使用 ((IAccount)this).AccountId
.
虽然处理这个问题的更简单方法是隐式实现接口,但事情会一直更自然一些。要隐式实现该接口,只需从其声明的开头删除 IAccount.
即可。有关隐式和显式接口的更多信息,请参阅 C# Interfaces. Implicit implementation versus Explicit implementation .
我是合同新手 我浏览了代码合同的 msdn 文档
https://msdn.microsoft.com/en-us/library/dd264808(v=vs.110).aspx
我选择了契约不变量的想法。但是,当我添加不变方法时,它不会访问字段表单接口。
[ContractClass(typeof(Account_Contract))]
public interface IAccount
{
int AccountID { get; }
string AccountOwner { get; }
int GetAccountID(); // Our 'internal'unique identifier for this account
}
[ContractClassFor(typeof(IAccount))]
internal abstract class Account_Contract : IAccount
{
int IAccount.AccountID
{
get
{
Contract.Ensures(Contract.Result<int>() > 0);
return default(int);
}
}
string IAccount.AccountOwner
{
get
{
Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));
return default(string);
}
}
int IAccount.GetAccountID()
{
Contract.Ensures(Contract.Result<int>() > 0);
return default(int);
}
}
它工作正常,但如果我添加
Contracts.Requires(AccountID > 0);
VS 不访问它。我也试过
Contracts.Requires(this.AccountID > 0);
Contracts.Requires(IAccount.AccountID > 0);
None 正在工作。我哪里做错了。
你的问题是你正在使用显式声明(因为@Chris 在他的回答中有评论),所以你必须将 this
转换为 IAccount
.
我认为你应该使用隐式声明(常用),因为IAccount
实现的所有方法和道具必须public。
隐式声明方式:
[ContractClassFor(typeof(IAccount))]
internal abstract class Account_Contract : IAccount
{
//In order to implement IAccount interface, must be public
public int AccountID
{
get
{
Contract.Requires(AccountID > 0);
return default(int);
}
}
//In order to implement IAccount interface, must be public
public string AccountOwner
{
get
{
Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));
return default(string);
}
}
//In order to implement IAccount interface, must be public
public int GetAccountID()
{
Contract.Ensures(Contract.Result<int>() > 0);
return default(int);
}
}
[ContractClass(typeof(Account_Contract))]
public interface IAccount
{
int AccountID { get; }
string AccountOwner { get; }
int GetAccountID(); ////Our 'internal'unique identifier for this account
}
编辑:我在这里包括@Cris 的回答。
显式声明方式:
[ContractClassFor(typeof(IAccount))]
internal abstract class Account_Contract : IAccount
{
int IAccount.AccountID
{
get
{
//You must cast this as IAccount
Contract.Requires(((IAccount)this).AccountID > 0);
return default(int);
}
}
string IAccount.AccountOwner
{
get
{
Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));
return default(string);
}
}
public int GetAccountID()
{
Contract.Ensures(Contract.Result<int>() > 0);
return default(int);
}
}
您正在使用接口的显式实现,这意味着如果您想将对象视为该接口的成员,那么您需要先转换为该接口。
因此,当您想要访问名为 myInstance
的实例上的 AccountID
时,您需要编写 ((IAccount)myInstance).AccountId
。如果您尝试直接在 class 上访问 AccountId
,那么它不会被识别。
这意味着如果您需要从 class 中为您的合约引用它,您应该使用 ((IAccount)this).AccountId
.
虽然处理这个问题的更简单方法是隐式实现接口,但事情会一直更自然一些。要隐式实现该接口,只需从其声明的开头删除 IAccount.
即可。有关隐式和显式接口的更多信息,请参阅 C# Interfaces. Implicit implementation versus Explicit implementation .