我从CodeContracts收到这些警告:
数组访问可能高于上限。你的意思是0而不是1吗? 数组访问可能高于上限。你的意思是1而不是2吗? 数组访问可能高于上限。你的意思是2而不是3吗? 数组访问可能高于上限。你的意思是3而不是4?
在这行代码中:
private readonly string[] _addr;
public string AddressLine1
{
get
{
return _addr[0] ?? _addr[1] ?? _addr[2] ?? _addr[3];
}
}
public string AddressLine2
{
get
{
return _addr[1] ?? _addr[2] ?? _addr[3];
}
}
public string AddressLine3
{
get
{
return _addr[2] ?? _addr[3];
}
}
如何告知Contracts分析仪这些指数是否在边界内得到保证? _addr
在构造函数中初始化为string[4]
。
答案 0 :(得分:4)
通过向定义不变量的类添加方法,我能够摆脱这些警告:
[ContractInvariantMethod]
private void AddressInvariants()
{
Contract.Invariant(_addr.Length == 4);
}
但是,我认为您的代码中也存在错误。
如果_addr[0] == null
和_addr[1] != null
,则AddressLine1
和AddressLine2
会返回相同的值。这似乎是一个错误。
您可以通过使用@ryanyuyu所提及的内容来轻松解决这个问题(并且无需指定契约不变量):
public string AddressLine1
{
get
{
// Use the first non-null element.
return _addr.Where(x => x != null).FirstOrDefault();
}
}
public string AddressLine2
{
get
{
// Use the second non-null element.
return _addr.Where(x => x != null).Skip(1).FirstOrDefault();
}
}
public string AddressLine3
{
get
{
// Use the third non-null element.
return _addr.Where(x => x != null).Skip(2).FirstOrDefault();
}
}
答案 1 :(得分:0)
ContractInvariantMethod
有效。但Contract.Assert()
也适用于局部变量。
static void MyParse(string foo)
{
string[] split = foo.Split(',');
Contract.Assert(split.Length == 4);
string a = split[0];
string b = split[1];
string c = split[2];
string d = split[3];
}
答案 2 :(得分:-1)
我不了解Contracts分析器,但您的代码可能更清晰。您基本上重复只找到第一个非空字符串的代码(如果最后一个元素为null,则无论如何都要返回)。我是使用LINQ .FirstOrDefault
的粉丝,它可以让你找到匹配条件的第一个元素(在你的情况下不是null)。如果没有找到这样的元素,它将返回默认值(对于一个字符串,它是null
)
return _addr.FirstOrDefault(str => str != null);
请参阅此.NET Fiddle。