Czy Mogę zainicjalizować atrybut C# za pomocą tablicy lub innej zmiennej liczby argumentów?
Czy jest możliwe utworzenie atrybutu, który może być zainicjalizowany zmienną liczbą argumentów?
Na przykład:
[MyCustomAttribute(new int[]{ 3, 4, 5})] // this doesn't work
public MyClass ...
7 answers
Atrybuty przyjmą tablicę. Chociaż jeśli kontrolujesz atrybut, możesz również użyć params
zamiast tego (co jest ładniejsze dla konsumentów, IMO):
class MyCustomAttribute : Attribute {
public int[] Values { get; set; }
public MyCustomAttribute(params int[] values) {
this.Values = values;
}
}
[MyCustomAttribute(3, 4, 5)]
class MyClass { }
Twoja składnia do tworzenia tablic jest wyłączona:
class MyCustomAttribute : Attribute {
public int[] Values { get; set; }
public MyCustomAttribute(int[] values) {
this.Values = values;
}
}
[MyCustomAttribute(new int[] { 3, 4, 5 })]
class MyClass { }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-01 15:56:19
Możesz to zrobić, ale nie jest to zgodne z CLS:
[assembly: CLSCompliant(true)]
class Foo : Attribute
{
public Foo(string[] vals) { }
}
[Foo(new string[] {"abc","def"})]
static void Bar() {}
Pokazuje:
Warning 1 Arrays as attribute arguments is not CLS-compliant
Dla regularnego użycia odbicia, może być lepiej mieć wiele atrybutów, np.
[Foo("abc"), Foo("def")]
Jednak to nie zadziała z TypeDescriptor
/PropertyDescriptor
, gdzie obsługiwana jest tylko jedna instancja dowolnego atrybutu (pierwsza lub ostatnia wygrywa, nie pamiętam który).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-13 00:09:10
Spróbuj zadeklarować konstruktor TAK:
public class MyCustomAttribute : Attribute
{
public MyCustomAttribute(params int[] t)
{
}
}
Wtedy możesz go użyć w następujący sposób:
[MyCustomAttribute(3, 4, 5)]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-06 20:49:50
Powinno być dobrze. Od spec, sekcja 17.2:
Wyrażenie E jest atrybutem-argumentem-wyrażeniem jeśli wszystkie poniższe wyrażenia są prawdziwe:
- typ E jest typem parametru atrybutowego (§17.1.3).
- w czasie kompilacji wartość E może być rozwiązana do jednej z następujących wartości:
- stała wartość.
- System.Wpisz obiekt.
- jednowymiarowa tablica atrybut-argument-wyrażenia .
Oto przykład:
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
{
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-06 20:49:08
Tak, ale musisz zainicjować tablicę, którą przekazujesz. Oto przykład z testu wiersza w naszych testach jednostkowych, który testuje zmienną liczbę opcji wiersza poleceń;
[Row( new[] { "-l", "/port:13102", "-lfsw" } )]
public void MyTest( string[] args ) { //... }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-06 20:48:45
Możesz to zrobić. Innym przykładem może być:
class MyAttribute: Attribute
{
public MyAttribute(params object[] args)
{
}
}
[MyAttribute("hello", 2, 3.14f)]
class Program
{
static void Main(string[] args)
{
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-06 20:50:49
Aby odpowiedzieć na pytanie marca Gravella, tak można zdefiniować atrybut z parametrami array, ale zastosowanie atrybutu z parametrem array nie jest zgodne z CLS. Jednak samo zdefiniowanie atrybutu z właściwością array jest całkowicie zgodne z CLS.
Uświadomiłem sobie, że Json.NET biblioteka zgodna z CLS posiada atrybut klasy JsonPropertyAttribute z właściwością ItemConverterParameters, która jest tablicą obiektów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-18 14:39:50