2011-12-22 19 views
5

Tôi muốn thực hiện các gợi ý sau đây từ CodeContracts:Tôi có thể sử dụng SuppressMessage trên phương pháp khung không?

CodeContracts: MyModule: Method MyModule.MyClass.MyMethod: 
To mask *all* warnings issued like the precondition add the attribute: 

[SuppressMessage("Microsoft.Contracts", "RequiresAtCall-propertyAccessor != null")] 

to the method 

System.Linq.Expressions.Expression.Property(System.Linq.Expressions.Expression,System.Reflection.MethodInfo) 

Nó cảm thấy như tôi sẽ có thể sử dụng SupressMessage với thuộc tính mục tiêu để thực hiện điều này. Tuy nhiên, vì đây là phương pháp Framework, tôi không chắc chắn.

//doesn't work 
[module: SuppressMessage("Microsoft.Contracts", "RequiresAtCall-propertyAccessor != null", Scope = "Member", Target = "System.Linq.Expressions.Expression.Property(System.Linq.Expressions.Expression,System.Reflection.MethodInfo)", Justification = "This isn't covered by Linq Contracts yet.")] 

Làm thế nào tôi có thể toàn cầu ngăn chặn cảnh báo này, vì vậy tôi không cần phải ban đầu hoặc ngăn chặn tất cả các cảnh báo callsite?

EDIT: The specific usage that requires this measure is: 

void mymethod() 
{ 
    var myObserver = new PropertyObserver<MyViewModel>(); 
    //this line throws the error, within the n => n.Value expression 
    myObserver.RegisterHandler(n => n.Value, OnValueChanged); 
} 

public class PropertyObserver<TPropertySource> where TPropertySource : INotifyPropertyChanged 
{ 
    public PropertyObserver<TPropertySource> RegisterHandler(
     Expression<Func<TPropertySource, object>> expression, 
     Action<TPropertySource> handler) 
    { 
     //what this does is irrelevant; the violation occurs in the method call 
    } 
} 

//n => n.Value decompiles to the following 
public static MemberExpression Property (Expression expression, MethodInfo propertyAccessor) 
{ 
    //and this line is the message I want to suppress, but it's in the .NET framework. 
    ContractUtils.RequiresNotNull(propertyAccessor, "propertyAccessor"); 
    ValidateMethodInfo(propertyAccessor); 
    return Property (expression, GetProperty(propertyAccessor)); 
} 
+0

Có một lý do mà bạn không sử dụng 'Contract.Assume'? Chỉ có quá nhiều lần xuất hiện? – porges

+0

Chúng tôi đã cố gắng tránh xa Contract.Assume nói chung, nhưng có, có một vài lần xuất hiện và chúng tôi tiếp tục bổ sung thêm. –

+0

Tôi đoán rằng vấn đề sau đó là các cách khác nhau để có được Expressions/MethodInfos không 'Đảm bảo 'rằng kết quả là không null. Bạn đã cân nhắc sử dụng một số phương pháp bao bọc như những phương pháp được đưa ra trong: http://social.msdn.microsoft.com/Forums/en-NZ/codecontracts/thread/d8e2c2ad-de37-42ef-a854-02052d821975? Bằng cách đó bạn chỉ cần 'Giả sử' ở một nơi, do đó, mức sử dụng' Giả sử' của bạn được giảm thiểu. – porges

Trả lời

3

Sau một số điều tra thêm với ranomore, có vẻ như có lỗi trong Hợp đồng mã.

Lớp học được truy cập qua n => n.Value có thuộc tính chung chung T Value. Nếu lớp được thay đổi thành một lớp không chung chung (với object Value), cảnh báo sẽ biến mất. (Một lớp học chung với object Value cũng đưa ra cảnh báo).

Tất nhiên, điều này không trả lời được câu hỏi ban đầu, nhưng tôi không nghĩ rằng có thể làm điều đó.

+0

Nó không được, hoặc người nào khác đã trả lời nó rồi. ;) –

-1

Xem nhanh tab Xây dựng thuộc tính dự án của bạn. Có trường "Cảnh báo ngăn chặn".

/nowarn (C# Compiler Options)

+1

Đây không phải là cảnh báo _compiler_, chúng là _code contract_ warning. Theo như tôi có thể nói, họ không có một số - vì vậy tôi không thể chỉ gọi/nowarn: 5275 –

+0

Ah, tôi đã không chú ý đủ gần! Đây là mức giá bạn phải trả để không ngủ. – Amy

+0

Vui lòng không đăng liên kết MSDN với số phiên bản trong đó, trừ khi bạn muốn trỏ đến một phiên bản tài liệu cụ thể. Vấn đề là mọi người bắt đầu nhấp vào các liên kết từ các trang đó và bắt đầu bị bắt, ví dụ, trong .NET 2.0-land. –

0
  1. Thêm GlobalSuppressions.cs đến thư mục gốc của dự án.

  2. Thêm [module của bạn ...

  3. Thay thế các mô-đun từ với lắp ráp.

Điều đó có hiệu quả không?

+0

Tôi đã có hy vọng cao, nhưng than ôi, nó không hoạt động. Tôi đã loại bỏ Phạm vi = "Thành viên" quá, chỉ trong trường hợp nó quan trọng. –

0

Nó thực sự hoạt động. Bạn có thể thêm SupressMessageAttribute vào phương thức chứa biểu thức. Chỉ cần không sử dụng RequiresAtCall. Thay vào đó, sử dụng Requires:

[SuppressMessage("Microsoft.Contracts", "Requires", 
       Justification = "Bug in static checker")] 
public void Override(AutoMapping<Bookings> mapping) 
{ 
    Contract.Assume(mapping != null); 

    mapping.Id(x => x.Id); 
} 

Nhược điểm rõ ràng là bạn sẽ phải thạch cao mã của bạn với những ...

+0

Chẳng phải điều đó khá nguy hiểm sao? Đó là _all_ yêu cầu bạn đang kìm nén ở đó. Tôi đã hy vọng sẽ ngăn chặn chỉ một tin nhắn. –

+0

@ranomore: Có, bạn cũng có thể chặn chỉ một tin nhắn này. Thay vì 'Yêu cầu', bạn phải sử dụng' Yêu cầu-11-10' trong đó các số xác định vị trí chính xác của cảnh báo. Bạn nhận được những con số đó từ các Hợp đồng Mã khi bạn thêm phần sau vào các lệnh bổ sung cho trình kiểm tra tĩnh trên trang thuộc tính của Chương trình Hợp đồng Mã: '-outputwarnmask'. Đối với mỗi cảnh báo nó sẽ xuất (trong cửa sổ Output, không có trong danh sách lỗi) một thông báo cung cấp cho bạn thuộc tính SupressMessage hoàn chỉnh mà bạn có thể sử dụng để chặn cảnh báo cụ thể đó. –

+0

Tôi đã không sử dụng này cho các lớp lập bản đồ NHibernate của tôi, bởi vì tôi đã quá lười biếng :) –

Các vấn đề liên quan