2008-11-06 49 views

Trả lời

142

Thuộc tính sẽ mất một mảng. Tuy nhiên nếu bạn kiểm soát các thuộc tính, bạn cũng có thể sử dụng params thay vì (đó là đẹp hơn cho người tiêu dùng, IMO):

class MyCustomAttribute : Attribute { 
    public int[] Values { get; set; } 

    public MyCustomAttribute(params int[] values) { 
     this.Values = values; 
    } 
} 

[MyCustomAttribute(3, 4, 5)] 
class MyClass { } 

cú pháp của bạn để tạo mảng chỉ xảy ra được off:

class MyCustomAttribute : Attribute { 
    public int[] Values { get; set; } 

    public MyCustomAttribute(int[] values) { 
     this.Values = values; 
    } 
} 

[MyCustomAttribute(new int[] { 3, 4, 5 })] 
class MyClass { } 
4

Vâng, nhưng bạn cần phải khởi tạo mảng mà bạn đang đi qua trong Dưới đây là một ví dụ từ một thử nghiệm liên tiếp trong các thử nghiệm đơn vị của chúng tôi kiểm tra một số biến các tùy chọn dòng lệnh. ;

[Row(new[] { "-l", "/port:13102", "-lfsw" })] 
public void MyTest(string[] args) { //... } 
12

Điều đó sẽ không sao. Từ spec, phần 17,2:

Một biểu thức E là một thuộc tính đối số biểu hiện nếu tất cả các câu sau đây là đúng:

  • Các loại E là một loại tham số thuộc tính (§17.1 .3).
  • Tại thời gian biên dịch, giá trị của E có thể được giải quyết theo một trong các cách sau:
    • Giá trị không đổi.
    • Đối tượng System.Type.
    • Mảng một chiều là thuộc tính-đối số-biểu thức.

Dưới đây là một ví dụ:

using System; 

[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)] 
public class SampleAttribute : Attribute 
{ 
    public SampleAttribute(int[] foo) 
    { 
    } 
} 

[Sample(new int[]{1, 3, 5})] 
class Test 
{ 
} 
+3

Xem ra để tuân thủ CLS, mặc dù –

16

Hãy thử tuyên bố các nhà xây dựng như thế này:

public class MyCustomAttribute : Attribute 
{ 
    public MyCustomAttribute(params int[] t) 
    { 
    } 
} 

Sau đó, bạn có thể sử dụng nó như:

[MyCustomAttribute(3, 4, 5)]

1

Bạn có thể làm điều đó. Một ví dụ khác có thể là:

class MyAttribute: Attribute 
{ 
    public MyAttribute(params object[] args) 
    { 
    } 
} 

[MyAttribute("hello", 2, 3.14f)] 
class Program 
{ 
    static void Main(string[] args) 
    { 
    } 
} 
30

Bạn có thể làm điều đó, nhưng nó không phải là CLS compliant:

[assembly: CLSCompliant(true)] 

class Foo : Attribute 
{ 
    public Foo(string[] vals) { } 
} 
[Foo(new string[] {"abc","def"})] 
static void Bar() {} 

cho thấy:

Warning 1 Arrays as attribute arguments is not CLS-compliant 

Để sử dụng phản chiếu thường xuyên, có thể thích hợp hơn để có nhiều thuộc tính, tức là

[Foo("abc"), Foo("def")] 

Tuy nhiên, điều này sẽ không làm việc với TypeDescriptor/PropertyDescriptor, nơi chỉ có một trường hợp duy nhất của bất kỳ thuộc tính được hỗ trợ (một trong hai chiến thắng đầu tiên hoặc cuối cùng, tôi không thể nhớ mà).

+3

lưu ý: nhiều thuộc tính yêu cầu thuộc tính AttributeUsage trên thuộc tính của bạn. http://stackoverflow.com/questions/553540/how-to-create-duplicate-allowed-attribute – russau

1

Để trả lời câu trả lời của Marc Gravell, bạn có thể xác định thuộc tính với tham số mảng nhưng áp dụng thuộc tính với tham số mảng không tuân thủ CLS. Tuy nhiên, việc xác định một thuộc tính với một thuộc tính mảng là hoàn toàn tuân thủ CLS.

Điều gì khiến tôi nhận ra điều này là Json.NET, một thư viện tuân thủ CLS, có một thuộc tính lớp JsonPropertyAttribute với một thuộc tính có tên ItemConverterParameters là một mảng các đối tượng.

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