В .Net, почему атрибуты, объявленные на интерфейсах, не возвращаются при вызове Type.GetCustomAttributes (true)? - PullRequest
5 голосов
/ 10 ноября 2010

В ответ на этот вопрос Я попытался использовать Type.GetCustomAttributes(true) в классе, который реализует интерфейс, для которого определен атрибут. Я был удивлен, обнаружив, что GetCustomAttributes не возвращает атрибут, определенный в интерфейсе. Почему не так? Разве интерфейсы не являются частью цепочки наследования?

Пример кода:

[Attr()]
public interface IInterface { }

public class DoesntOverrideAttr : IInterface { }

class Program
{
    static void Main(string[] args)
    {
        foreach (var attr in typeof(DoesntOverrideAttr).GetCustomAttributes(true))
            Console.WriteLine("DoesntOverrideAttr: " + attr.ToString());
    }
}

[AttributeUsage(AttributeTargets.All, Inherited = true)]
public class Attr : Attribute
{
}

Выходы: ничего

Ответы [ 2 ]

9 голосов
/ 10 ноября 2010

Я не верю, что атрибуты, определенные в реализованных интерфейсах, могут быть разумно унаследованы. Рассмотрим этот случай:

[AttributeUsage(Inherited=true, AllowMultiple=false)]
public class SomethingAttribute : Attribute {
    public string Value { get; set; }

    public SomethingAttribute(string value) {
        Value = value;
    }
}

[Something("hello")]
public interface A { }

[Something("world")]
public interface B { }

public class C : A, B { }

Поскольку атрибут указывает, что мультипликаторы недопустимы, как можно ожидать, что эта ситуация будет обработана?

4 голосов
/ 10 ноября 2010

Поскольку тип DoesntOverrideAttr не имеет никаких пользовательских атрибутов.Интерфейс, который он реализует, делает (помните, класс не наследует от интерфейса ... он реализует его, поэтому получение атрибутов вверх по цепочке наследования по-прежнему не будет включать атрибуты интерфейсов):

// This code doesn't check to see if the type implements the interface.
// It should.
foreach(var attr in typeof(DoesntOverrideAttr)
                        .GetInterface("IInterface")
                        .GetCustomAttributes(true))
{
    Console.WriteLine("IInterface: " + attr.ToString());
}
...