Powoduje to wyjątek czasu kompilacji:
public sealed class ValidatesAttribute<T> : Attribute
{
}
[Validates<string>]
public static class StringValidation
{
}
Wiem, że C # nie obsługuje atrybutów ogólnych. Jednak po długim Googlingu nie mogę znaleźć powodu.
Czy ktoś wie, dlaczego typy ogólne nie mogą pochodzić Attribute
? Jakieś teorie?
c#
generics
.net-attributes
Bryan Watts
źródło
źródło
abstract class Base<T>: Attribute {}
które można wykorzystać do tworzenia innych niż ogólne klasy pochodne, takie jak:class Concrete: Base<MyType> {}
[DependsOnProperty<Foo>(f => f.Bar)]
lub[ForeignKey<Foo>(f => f.IdBar)]
...Odpowiedzi:
Cóż, nie mogę odpowiedzieć, dlaczego nie jest dostępny, ale może potwierdzić, że to nie jest kwestia CLI. Specyfikacja CLI nie wspomina o tym (o ile widzę) i jeśli używasz IL bezpośrednio, możesz utworzyć atrybut ogólny. Część specyfikacji C # 3, która ją zakazuje - sekcja 10.1.4 „Podstawowa specyfikacja klasy” nie daje żadnego uzasadnienia.
Adnotacja specyfikacji ECMA C # 2 również nie zawiera żadnych pomocnych informacji, chociaż stanowi przykład tego, co jest niedozwolone.
Moja kopia specyfikacji C # 3 z adnotacjami powinna przyjechać jutro ... Zobaczę, czy to da więcej informacji. W każdym razie zdecydowanie jest to decyzja językowa, a nie decyzja w czasie wykonywania.
EDYCJA: Odpowiedź Erica Lipperta (sparafrazowana): bez konkretnego powodu, z wyjątkiem uniknięcia złożoności zarówno w języku, jak i kompilatorze dla przypadku użycia, który nie wnosi dużej wartości.
źródło
Atrybut ozdabia klasę w czasie kompilacji, ale klasa ogólna nie otrzymuje informacji o ostatecznym typie do czasu uruchomienia. Ponieważ atrybut może wpływać na kompilację, musi być „kompletny” w czasie kompilacji.
Więcej informacji można znaleźć w tym artykule MSDN .
źródło
Nie wiem, dlaczego jest to niedozwolone, ale jest to jedno z możliwych obejść
źródło
Nie jest to naprawdę ogólne i nadal musisz napisać konkretną klasę atrybutów dla każdego typu, ale możesz być w stanie użyć ogólnego interfejsu podstawowego, aby trochę defensywnie kodować, pisać mniejszy kod niż jest to wymagane, uzyskać korzyści z polimorfizmu itp.
źródło
To jest bardzo dobre pytanie. Z mojego doświadczenia z atrybutami, myślę, że ograniczenie jest na miejscu, bo kiedy zastanawia się nad atrybutem byłoby stworzyć warunki, w których będzie trzeba sprawdzić dla wszystkich możliwych permutacji typu:
typeof(Validates<string>)
,typeof(Validates<SomeCustomType>)
, etc ...Moim zdaniem, jeśli wymagane jest niestandardowe sprawdzenie poprawności w zależności od typu, atrybut może nie być najlepszym podejściem.
Być może lepszym podejściem byłaby klasa walidacyjna, która przyjmuje parametr a
SomeCustomValidationDelegate
lub aISomeCustomValidator
jako parametr.źródło
Obecnie nie jest to funkcja języka C #, jednak wiele dyskusji dotyczy oficjalnego repozytorium języka C # .
Z niektórych notatek ze spotkania :
źródło
Moje obejście jest mniej więcej takie:
źródło