Минутка WTF-14: не повторяясь
От: Sinix  
Дата: 08.01.17 18:21
Оценка: 4 (1)
Таки снова да
Автор: Sinix
Дата: 07.12.16
.

using System;
using ConsoleApp;

[assembly: My("A"), My("A"), My("B")]

namespace ConsoleApp
{
    [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
    public class MyAttribute : Attribute
    {
        public MyAttribute(string origin)
        {
            Origin = origin;
        }

        public string Origin { get; }
    }

    [My("A"), My("A"), My("B")]
    class Program
    {
        static void Main(string[] args)
        {
            var t = typeof(Program);
            Console.WriteLine(
                "Type-level: {0} attributes",
                Attribute.GetCustomAttributes(t, typeof(MyAttribute)).Length);
            Console.WriteLine(
                "Assembly-level: {0} attributes",
                Attribute.GetCustomAttributes(t.Assembly, typeof(MyAttribute)).Length);

            Console.ReadKey();
        }
    }
}


Кто объяснит вывод — тому медаль. Воспроизводится как минимум на компиляторах c#5 и выше. Вывод отдельным ответом ибо спойлер.
минутка wtf
Re: Минутка WTF-14: не повторяясь
От: Sinix  
Дата: 08.01.17 18:25
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Вывод отдельным ответом ибо спойлер.

  ибо спойлер
Type-level: 3 attributes
Assembly-level: 2 attributes


как-то так, да.
Re[2]: Минутка WTF-14: не повторяясь
От: dmitry_npi Россия  
Дата: 09.01.17 10:21
Оценка: 72 (1) +1
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Sinix, Вы писали:


S>>Вывод отдельным ответом ибо спойлер.

S>
  ибо спойлер
S>
S>Type-level: 3 attributes
S>Assembly-level: 2 attributes
S>


S>как-то так, да.



Почему выводится это, понять можно: дизассемблировав сборку, видно, что повторяющийся атрибут туда просто не попал. (я имею в виду атрибут сборки, на атрибуты класса можно вообще забить).
Также можно упростить код атрибута до
public MyAttribute(string origin)
{
  // пусто           
}


То есть, мы можем сказать, что метод GetCustomAttributes тут ни при чём, просто компилятор не поместил повторяющийся атрибут в сборку, причём "одинаковость" он определяет только по параметрам конструктора, остальное (свойства) в счёт не идет.
Кстати, можно дизассемблировать сборку, прописать туда "пропавший" атрибут по аналогии и ассемблировать снова. Тогда получим ожидаемый результат.

Так что вопрос сводится к "зачем они так сделали?". Тут могут быть варианты:
Атмосферная музыка — www.aventuel.net
Отредактировано 09.01.2017 10:28 dmitry_npi . Предыдущая версия .
Re[3]: Минутка WTF-14: не повторяясь
От: Sinix  
Дата: 09.01.17 10:34
Оценка:
Здравствуйте, dmitry_npi, Вы писали:

_>То есть, мы можем сказать, что метод GetCustomAttributes тут ни при чём, просто компилятор не поместил повторяющийся атрибут в сборку, причём "одинаковость" он определяет только по параметрам конструктора, остальное (свойства) в счёт не идет.

Таки да, тема раскрыта полностью

_>Так что вопрос сводится к "зачем они так сделали?". Тут могут быть варианты:

Ну, поведение тянется ещё с c# 3 (древнее лень проверять) + в первом рослине огромное количество времени уделяли полному совпадению il-выхлопа для существующего кода на c#, вплоть до тестов с компиляцией всего опенсорс-кода на шарпе на codeproject / codeplex (по памяти, поэтому без пруфов). Т.е. почему не поменялось сразу — понятно.

Позднее, разумеется, пошли ломающие изменения, так что в принципе, может быть поправлено. В c# spec это нигде не оговорено (или я пропустил), в mono (онлайн-сервис для проверки) поведение логичное —
Type-level: 3 attributes
Assembly-level: 3 attributes


Issue завёл, посмотрим, что ответят.
Re[4]: Минутка WTF-14: не повторяясь
От: Sharov Россия  
Дата: 09.01.17 11:49
Оценка:
Здравствуйте, Sinix, Вы писали:

_>>Так что вопрос сводится к "зачем они так сделали?". Тут могут быть варианты:

S>Ну, поведение тянется ещё с c# 3 (древнее лень проверять) + в первом рослине огромное количество времени уделяли полному совпадению il-выхлопа для существующего кода на c#, вплоть до тестов с компиляцией всего опенсорс-кода на шарпе на codeproject / codeplex (по памяти, поэтому без пруфов). Т.е. почему не поменялось сразу — понятно.

Поведение на всех версиях языка для vs2013 одинаковое.

S>Позднее, разумеется, пошли ломающие изменения, так что в принципе, может быть поправлено. В c# spec это нигде не оговорено (или я пропустил), в mono (онлайн-сервис для проверки) поведение логичное —

S>
S>Type-level: 3 attributes
S>Assembly-level: 3 attributes
S>


Мне кажется что 2-2 будет логичнее чем 3-3. Какой смысл навешивать дважды один и тот же атрибут?
Кодом людям нужно помогать!
Re[5]: Минутка WTF-14: не повторяясь
От: Sinix  
Дата: 09.01.17 11:58
Оценка: 4 (1)
Здравствуйте, Sharov, Вы писали:

S>Мне кажется что 2-2 будет логичнее чем 3-3. Какой смысл навешивать дважды один и тот же атрибут?

AOP-декораторы, к примеру. Комбо из [LogStartEndTime][TakeLock][LogStartEndTime] — вполне себе реальное (хотя работает чисто по везению, т.к. строго говоря компилятор не обязан сохранять порядок следования атрибутов).
Re[6]: Минутка WTF-14: не повторяясь
От: Sharov Россия  
Дата: 09.01.17 12:10
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Sharov, Вы писали:


S>>Мне кажется что 2-2 будет логичнее чем 3-3. Какой смысл навешивать дважды один и тот же атрибут?

S>AOP-декораторы, к примеру. Комбо из [LogStartEndTime][TakeLock][LogStartEndTime] — вполне себе реальное (хотя работает чисто по везению, т.к. строго говоря компилятор не обязан сохранять порядок следования атрибутов).

Про AOP не думал, возможно и так. Но вообще суть метаданных в их уникальности или однозначности.
Кодом людям нужно помогать!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.