Wydaje się, że oznacza to „nie”. Co jest niefortunne.
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class,
AllowMultiple = true, Inherited = true)]
public class CustomDescriptionAttribute : Attribute
{
public string Description { get; private set; }
public CustomDescriptionAttribute(string description)
{
Description = description;
}
}
[CustomDescription("IProjectController")]
public interface IProjectController
{
void Create(string projectName);
}
internal class ProjectController : IProjectController
{
public void Create(string projectName)
{
}
}
[TestFixture]
public class CustomDescriptionAttributeTests
{
[Test]
public void ProjectController_ShouldHaveCustomDescriptionAttribute()
{
Type type = typeof(ProjectController);
object[] attributes = type.GetCustomAttributes(
typeof(CustomDescriptionAttribute),
true);
// NUnit.Framework.AssertionException: Expected: 1 But was: 0
Assert.AreEqual(1, attributes.Length);
}
}
Czy klasa może dziedziczyć atrybuty z interfejsu? A może szczekam tutaj na niewłaściwe drzewo?
c#
attributes
Roger Lipscombe
źródło
źródło
Możesz zdefiniować przydatną metodę rozszerzenia ...
Oto metoda rozszerzenia:
Aktualizacja:
Oto krótsza wersja zaproponowana przez SimonD w komentarzu:
źródło
Apply
wbudowanymForEach
odMicrosoft.Practices.ObjectBuilder2
Artykuł autorstwa Brada Wilsona na ten temat: Atrybuty interfejsu! = Atrybuty klas
Podsumowując: klasy nie dziedziczą po interfejsach, tylko je implementują. Oznacza to, że atrybuty nie są automatycznie częścią implementacji.
Jeśli musisz dziedziczyć atrybuty, użyj abstrakcyjnej klasy bazowej zamiast interfejsu.
źródło
Chociaż klasa C # nie dziedziczy atrybutów ze swoich interfejsów, istnieje przydatna alternatywa podczas wiązania modeli w ASP.NET MVC3.
Jeśli zadeklarujesz model widoku jako interfejs, a nie konkretny typ, widok i spinacz modelu zastosują atrybuty (np.
[Required]
Lub[DisplayName("Foo")]
z interfejsu podczas renderowania i walidacji modelu:Następnie w widoku:
źródło
Jest to bardziej dla osób, które chcą wyodrębnić atrybuty z właściwości, które mogą istnieć w zaimplementowanym interfejsie. Ponieważ te atrybuty nie są częścią klasy, daje to dostęp do nich. uwaga, mam prostą klasę kontenera, która daje dostęp do PropertyInfo - ponieważ do tego potrzebowałem. Hakuj tak, jak potrzebujesz. To działało dobrze dla mnie.
źródło
EDYCJA: obejmuje dziedziczenie atrybutów z interfejsów na elementach (w tym właściwości). Powyżej znajdują się proste odpowiedzi dotyczące definicji typów. Właśnie to opublikowałem, ponieważ uznałem to za irytujące ograniczenie i chciałem podzielić się rozwiązaniem :)
Interfejsy są dziedziczone wielokrotnie i zachowują się jak dziedziczenie w systemie typów. Nie ma dobrego powodu dla tego rodzaju rzeczy. Odbicie jest trochę szalone. Dodałem komentarze, aby wyjaśnić bzdury.
(To jest .NET 3.5, ponieważ tak się składa, że właśnie tego używa projekt, którego obecnie używam).
Test Barebones NUnit
źródło
Dodaj interfejs z właściwościami, które mają atrybuty / atrybuty niestandardowe dołączone do tych samych właściwości, które ma klasa. Możemy wyodrębnić interfejs klasy za pomocą funkcji refaktoryzacji programu Visual Studio. Niech część klasy implementuje ten interfejs.
Teraz pobierz obiekt „Type” obiektu klasy i uzyskaj niestandardowe atrybuty z informacji o właściwościach za pomocą funkcji getProperties w obiekcie Type. Nie spowoduje to nadania atrybutów niestandardowych w obiekcie klasy, ponieważ właściwości klasy nie miały dołączonych / odziedziczonych atrybutów niestandardowych właściwości interfejsu.
Teraz wywołaj GetInterface (NameOfImplemetedInterfaceByclass) na pobranym powyżej obiekcie Type klasy. Zapewni to obiekt „Type” interfejsu. powinniśmy znać NAZWĘ zaimplementowanego interfejsu. Z obiektu Type pobierz informacje o właściwościach, a jeśli właściwość interfejsu ma dołączone atrybuty niestandardowe, informacje o właściwości będą zawierać listę atrybutów niestandardowych. Klasa implementująca musi mieć implementację właściwości interfejsu. Dopasuj nazwę właściwości obiektu klasy na liście informacji o właściwościach interfejsu, aby uzyskać listę atrybutów niestandardowych.
To zadziała.
źródło
Chociaż moja odpowiedź jest spóźniona i dotyczy konkretnego przypadku, chciałbym dodać kilka pomysłów. Jak sugerowano w innych odpowiedziach, wystarczyłoby Refleksja lub inne metody.
W moim przypadku właściwość (sygnatura czasowa) była potrzebna we wszystkich modelach, aby spełnić określone wymaganie (atrybut sprawdzania współbieżności) w podstawowym projekcie Entity Framework. Mogliśmy albo dodać [] przede wszystkim właściwości klasy (dodanie w interfejsie IModel, który model jest zaimplementowany, nie działa). Ale zaoszczędziłem czas dzięki Fluent API, które jest pomocne w takich przypadkach. Korzystając z płynnego API, mogę sprawdzić konkretną nazwę właściwości we wszystkich modelach i ustawić jako IsConcurrencyToken () w 1 linii !!
Podobnie, jeśli potrzebujesz dodać atrybut do tej samej nazwy właściwości w setkach klas / modeli, możemy użyć metod Fluent API dla wbudowanego lub niestandardowego rozpoznawania atrybutów. Chociaż EF (zarówno rdzeń, jak i EF6) Fluent API może używać refleksji za kulisami, możemy zaoszczędzić wysiłku :)
źródło