코드 계약서는 "LINQ 문의 가능성이있는 메서드 호출"경고를 내 LINQ 문의 모든 것에 대해 계속 제공하며 침묵 할 수있는 방법을 찾을 수 없습니다. 예를 들어, 다음 메소드는 null을 먼저 확인하지 않고 "car"객체의 "Make"및 "Model"속성에 액세스하기 때문에 두 가지 경고를 생성합니다. 내 특정 경우코드 계약을 LINQ와 함께 사용할 수있는 방법이 있습니까?
public IEnumerable<string> GetCarModelsByMake(string make)
{
return from car in Cars
where car.Make == make
select car.Model;
}
, 나는 자동차 컬렉션에 null 항목을 포함하지 않을 것이라는 점을 알고있다, 그래서 내가 그냥가, 정적 검사를 침묵과 같이하는 방법에 가정 추가 할 수 있습니다 생각 :
public IEnumerable<string> GetCarModelsByMake(string make)
{
Contract.Assume(Cars.All(car => car != null));
return from car in Cars
where car.Make == make
select car.Model;
}
그러나 그것은 작동하지 않습니다. 아마 정적 검사기가 이해하기가 너무 많기 때문입니다. 따라서 다음 SuppressMessage 특성을 사용하여 경고를 표시하지 않기로 결정했습니다.
[SuppressMessage("Microsoft.Contracts", "NonNull")]
그러나 어떤 이유로 든 경고를 표시하지 못합니다.
[SuppressMessage("Microsoft.Contracts", "Requires")]
[SuppressMessage("Microsoft.Contracts", "Ensures")]
[SuppressMessage("Microsoft.Contracts", "Invariant")]
나는 심지어 ContractVerification 속성을 사용하는 방법을 완전히 비활성화 계약 검증하려 :
[ContractVerification(false)]
을하지만 그건하지 않았다 난 일 어느 것도, 다음 SuppressMessage뿐만 아니라 속성 시도 어느 쪽이든 일하십시오. 그래서, 난 그냥 LINQ 문의 "여기서"절에 명시 적으로 널 (null) 검사를 추가 할 것입니다 결정 :
public IEnumerable<string> GetCarModelsByMake(string make)
{
return from car in Cars
where car != null && car.Make == make
select car.Model;
}
성공적 "여기서"절에 경고를 제거한다, 그러나 그렇지 않습니다 "select"절에 대한 경고를 제거하십시오. 사실, 실제로 모두 경고를 제거하기 위해 찾은 유일한 방법은 지금처럼 LINQ 문에 모든 절에 널 (null) 검사를 추가하는 것입니다 : 분명히
public IEnumerable<string> GetCarModelsByMake(string make)
{
return from car in Cars
where car != null && car.Make == make
select car == null ? null : car.Model;
}
, 즉없는 매우 깨끗 또는 효율적인 코드 , 그리고 실제로 모든 LINQ 문에 이러한 중복 null 검사를 추가 할 생각은 없습니다. 특히 열거 형에 null 항목이 포함되어 있지 않은 경우에는주의해야합니다. 이 문제를 해결하는 최선의 방법은 정적 검사기가 컬렉션의 각 항목에 대해 null이 아닌 값을 보장하는 Contract.Assume 문을 이해할 수 있지만 그렇게 할 수없는 경우 메서드의 SuppressMessage 특성을 준수하는 것입니다 .
+1하지만 나는'Cars!= null '을 클래스 불변 식이자는 원래 코드의 정신에 더 가깝게 머물 것인데, 이는 분명히'자동차 '가'null '이 될 것으로 기대하지 않습니다. http://msdn.microsoft.com/en-us/magazine/ee236408.aspx#id0070066 –
물론입니다. 이 클래스의 불변량은이 질문의 코드 계약 성격에 더 적합합니다. –
클래스에 이미 Cars! = null을 보장하는 불변성이 있음을 분명히 했어야합니다. 그것은 계약 경고에 관한 것이 아닙니다. 경고는 "car"컬렉션이 아니라 "car"변수가 null 인 것에 대한 것입니다. –