2009-10-01 30 views
8

Tôi đã nghĩ rằng nó sẽ hữu ích để có thể làm một điều như vậy, ví dụ, để kiểm tra các tham số cho tham chiếu null và cuối cùng ném một ngoại lệ.
Điều này sẽ tiết kiệm được một số thao tác nhập và cũng sẽ khiến bạn không thể quên thêm một kiểm tra nếu một thông số mới được thêm vào.Có thể lặp qua các tham số của phương thức trong C# không?

Trả lời

15

Vâng, không trừ khi bạn đếm:

public void Foo(string x, object y, Stream z, int a) 
{ 
    CheckNotNull(x, y, z); 
    ... 
} 

public static void CheckNotNull(params object[] values) 
{ 
    foreach (object x in values) 
    { 
     if (x == null) 
     { 
      throw new ArgumentNullException(); 
     } 
    } 
} 

Để tránh các hit tạo mảng, bạn có thể có một số quá tải cho các số khác nhau của các đối số:

public static void CheckNotNull(object x, object y) 
{ 
    if (x == null || y == null) 
    { 
     throw new ArgumentNullException(); 
    } 
} 

// etc 

Một thay thế sẽ được sử dụng các thuộc tính để khai báo rằng các tham số không được rỗng và nhận được PostSharp để tạo các séc thích hợp:

public void Foo([NotNull] string x, [NotNull] object y, 
       [NotNull] Stream z, int a) 
{ 
    // PostSharp would inject the code here. 
} 

Phải thừa nhận rằng tôi có thể muốn PostSharp chuyển đổi nó thành các cuộc gọi Code Contracts, nhưng tôi không biết hai người chơi cùng nhau như thế nào. Có lẽ một ngày chúng ta sẽ có thể viết SpeC# -like:

public void Foo(string! x, object! y, Stream! z, int a) 
{ 
    // Compiler would generate Code Contracts calls here 
} 

... nhưng không phải trong tương lai gần :)

+0

Trong trường hợp của bạn những gì về CheckNotNull ((object []) null)? :-) –

+1

Hãy suy nghĩ tác giả có nghĩa là một cái gì đó giống như từ khóa đối số của javascript. Ví dụ. liệt kê tất cả các đối số trong phương thức "Foo (string x, object y, Stream z, int a)" và kiểm tra chúng cho null mà không chỉ định từng cái, nhưng gọi một số phương thức chung như "ValidateArgs (Foo.arguments);" . – Kamarey

+0

@ Dzmitry: Vâng, vâng - bạn chưa hoàn toàn sẵn sàng sản xuất :) –

0

Có thể lặp qua các thông số đã được công bố cho một phương pháp (thông qua phản ánh), nhưng tôi thấy không có cách nào để lấy giá trị của những thông số cho một cuộc gọi phương pháp cụ thể ...

Có lẽ bạn có thể sử dụng Postsharp và tạo một khía cạnh ở nơi bạn thực hiện kiểm tra này. Sau đó, tại thời gian biên dịch, PostSharp có thể 'dệt' khía cạnh (tiêm mã bổ sung) tại tất cả các phương pháp mà bạn đã viết ...

0

Bạn có thể nhìn vào The Validation Application Block có thể được coi là một ví dụ về xác nhận tự động và The Unity Application Block (đặc biệt là tính năng đánh chặn của nó) liên quan đến việc chặn các cuộc gọi và kiểm tra các tham số.

2

Bạn có thể xác định tham số phương pháp với một từ khóa params. Điều này sẽ làm cho nó có thể vượt qua một số biến chiều dài của các tham số cho phương pháp của bạn. Sau đó bạn có thể lặp lại chúng và kiểm tra các tham chiếu null hoặc bất cứ điều gì bạn muốn với nó.

public void MyMethod(params object[] parameters) { 
    foreach (var p in parameters) { 
     ... 
    } 
} 

// method call: 
this.MyMethod("foo", "bar", 123, null, new MyClass()); 

Tuy nhiên, theo tôi, đây không phải là cách làm tốt. Bạn sẽ phải tự kiểm soát loại tham số của bạn, vị trí của chúng trong mảng đầu vào và bạn sẽ không thể sử dụng intellisense cho chúng trong Visual Studio.

0

Bạn hoàn toàn có thể tự động kiểm tra thông số bằng thư viện AOP chẳng hạn như PostSharp.

1

Tôi đã có cùng một câu hỏi một thời gian trước đây, nhưng muốn làm như vậy cho mục đích ghi nhật ký. Tôi không bao giờ tìm thấy một giải pháp tốt, nhưng tìm thấy liên kết này liên quan đến việc sử dụng phương pháp tiếp cận dựa trên AOP cho mục nhập phương thức ghi nhật ký và thoát. Ý chính của nó là cần phải sử dụng một khuôn khổ có thể đọc lớp của bạn và mã tiêm vào thời gian chạy để làm những gì bạn đang cố gắng làm. Nghe không dễ.

How do I intercept a method call in C#?

0

Sau khi cung cấp một ví dụ tầm thường của một phương pháp sử dụng từ khóa params, RaYell nói:

Theo tôi tuy nhiên, nó không phải là một cách tốt để làm việc. Bạn sẽ phải điều khiển theo cách thủ công loại thông số của bạn, vị trí của chúng trong mảng nhập và bạn sẽ không thể sử dụng intellisense cho chúng trong Visual Studio.

tôi sẽ chắc chắn đồng ý rằng tuyên bố một phương pháp mà phải mất hai strings, một int, một object có thể được null, và một MyClass đối tượng sử dụng params là một ý tưởng tồi. Tuy nhiên, có (theo ý kiến ​​của tôi) hoàn toàn hợp lệ và thích hợp các ứng dụng của từ khóa params, cụ thể là khi các tham số là tất cả cùng loại. Ví dụ:

public T Max<T>(T x, T y) where T : IComparable<T> { 
    return x.CompareTo(y) > 0 ? x : y; 
} 

public T Max<T>(params T[] values) where T : IComparable<T> { 
    T maxValue = values[0]; 

    for (int i = 1; i < values.Length; i++) { 
     maxValue = Max<T>(maxValue, values[i]); 
    } 

    return maxValue; 
} 
0
var mandatoryFields = (new object[] { input1, input2 }).Where(v => v == null || v.ToString().Trim() == ""); 

Bạn sẽ nhận được danh sách các thông số null.

Vì vậy, sau đó bạn chỉ có thể thêm

if(mandatoryFields.ToArray().Count > 0){} 
Các vấn đề liên quan