Подтвердить что ты не робот

Почему наилучшая практика .NET разрабатывать пользовательские атрибуты как запечатанные?

Я читаю Pro С# 2010 и платформу .Net 4 от Andrew Troelsen.

В главе 15 об атрибутах существует примечание:

Примечание.. По соображениям безопасности считается наилучшей практикой .Net для разработки всех настраиваемых атрибутов как запечатанных.

Автор не объясняет, почему, может кто-нибудь объяснить, почему?

4b9b3361

Ответ 1

CA1813: Избегайте незапечатанных атрибутов: Библиотека классов .NET Framework предоставляет методы для извлечения пользовательские атрибуты. По умолчанию эти методы выполняют поиск по атрибуту иерархия наследования; например Attribute.GetCustomAttribute ищет указанный тип атрибута или любой тип атрибута, который расширяет указанный тип атрибута. Уплотнение атрибута устраняет поиск по иерархии наследования и может улучшить производительность.

Ссылка: http://msdn.microsoft.com/en-us/library/ms182267(v=VS.100).aspx

Атрибуты - это просто метаданные, обнаруженные во время выполнения. Как это указано, если кто-то другой вытекает из вашего настраиваемого класса атрибутов, по умолчанию .NET тоже найдет их, что может означать риск безопасности, если производный класс атрибутов изменяет поведение вашего исходного атрибута таким образом, который вы никогда не планировали к.

Несмотря на то, что производительность является основной причиной для печати классов атрибутов, вот грозная статья, посвященная ее стороне безопасности: http://alabaxblog.info/?p=44 p >

Ответ 2

Есть еще одна причина для печати атрибутов.

Рассмотрим следующий атрибут:

[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false)]
public class Attr1 : Attribute
{
}

Здесь вы разрешаете только одно украшение атрибута: AllowMultiple = false

Компилятор не допустит этого:

[Attr1]
[Attr1]
public class Foo
{
}

Позже в коде вы можете безопасно вызвать memberInfo.GetCustomAttribute(), который будет бросать AmbiguousMatchException, если было найдено более одного атрибута данного типа.

Теперь наследуем:

public class Attr2 : Attr1
{
}

Теперь компилятор не работает.

[Attr1]
[Attr2]
public class Foo
{
}

Итак, если позже кто-то наследует ваш атрибут и возвращается обратно к вашему коду, будет выброшен какой-либо объект, помеченный обоим атрибутом, неожиданное исключение.

Полный пример:

class Program
{
    static void Main(params string[] args)
    {
        typeof(Foo).GetCustomAttribute<Attr1>();
    }

    [AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public class Attr1 : Attribute
    {
    }

    public class Attr2 : Attr1
    {
    }

    [Attr1]
    [Attr2]
    public class Foo
    {
    }

    [Attr1]
    public class Bar : Foo
    {
    }
}

Ответ 3

Руководство по дизайну рамок: соглашения, идиомы и шаблоны для многоразовых библиотек .NET просто говорит:

DO запечатывайте специальные классы атрибутов, если это возможно. Это ускоряет поиск атрибута.

Я ничего не видел о безопасности в этом разделе, но @Teoman Soygul делает хороший момент. Поэтому я согласен с мистером Троелсеном.