Как перечислить все классы с пользовательским атрибутом класса?

Используйте функции number_format() и rtrim() вместе. Например:

//eg $sciNotation = 2.3649E-8
$number = number_format($sciNotation, 10); //Use $dec_point large enough
echo rtrim($number, '0'); //Remove trailing zeros

Я создал функцию с большим количеством функций (каламбур не предназначен)

function decimalNotation($num){
    $parts = explode('E', $num);
    if(count($parts) != 2){
        return $num;
    }
    $exp = abs(end($parts)) + 3;
    $decimal = number_format($num, $exp);
    $decimal = rtrim($decimal, '0');
    return rtrim($decimal, '.');
}
140
задан c24w 24 October 2018 в 10:45
поделиться

3 ответа

Да, абсолютно. Использование Отражения:

static IEnumerable<Type> GetTypesWithHelpAttribute(Assembly assembly) {
    foreach(Type type in assembly.GetTypes()) {
        if (type.GetCustomAttributes(typeof(HelpAttribute), true).Length > 0) {
            yield return type;
        }
    }
}
188
ответ дан Andrew Arnott 24 October 2018 в 10:45
поделиться

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

Это - отрывок моего кода, который пробегает все типы во всех загруженных блоках:

// this is making the assumption that all assemblies we need are already loaded.
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) 
{
    foreach (Type type in assembly.GetTypes())
    {
        var attribs = type.GetCustomAttributes(typeof(MyCustomAttribute), false);
        if (attribs != null && attribs.Length > 0)
        {
            // add to a cache.
        }
    }
}
10
ответ дан joce 24 October 2018 в 10:45
поделиться
  • 1
    Я надеюсь Вы don' t ум - imgur не заблокирован на моей работе, таким образом, я шел вперед и добавил Ваше изображение. Я думаю, что оба подхода являются хорошими решениями этого вопроса! – Hooked 14 April 2014 в 14:15

Ну, необходимо было бы перечислить через все классы во всех блоках, которые загружаются в текущий домен приложения. Чтобы сделать это, Вы звонили бы GetAssemblies метод на AppDomain экземпляр для текущего домена приложения.

Оттуда, Вы звонили бы GetExportedTypes (если Вы только хотите открытые типы), или GetTypes на каждом Assembly для получения типов, которые содержатся в блоке.

Затем Вы звонили бы GetCustomAttributes дополнительный метод на каждом Type экземпляр, передавая тип атрибута, который Вы хотите найти.

можно использовать LINQ для упрощения этого для Вас:

var typesWithMyAttribute =
    from a in AppDomain.CurrentDomain.GetAssemblies()
    from t in a.GetTypes()
    let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
    where attributes != null && attributes.Length > 0
    select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };

вышеупомянутый запрос получит Вас, каждый тип с Вашим атрибутом относился к нему, наряду с экземпляром атрибута (атрибутов), присвоенного ему.

Примечание, что, если у Вас есть большое количество блоков, загруженных в Ваш домен приложения, что операция могла быть дорогой. Можно использовать Параллельный LINQ для сокращения времени операции, как так:

var typesWithMyAttribute =
    // Note the AsParallel here, this will parallelize everything after.
    from a in AppDomain.CurrentDomain.GetAssemblies().AsParallel()
    from t in a.GetTypes()
    let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
    where attributes != null && attributes.Length > 0
    select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };

Фильтрация его на определенном Assembly проста:

Assembly assembly = ...;

var typesWithMyAttribute =
    from t in assembly.GetTypes()
    let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
    where attributes != null && attributes.Length > 0
    select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };

И если блок имеет большое количество типов в нем, то можно использовать Параллельный LINQ снова:

Assembly assembly = ...;

var typesWithMyAttribute =
    // Partition on the type list initially.
    from t in assembly.GetTypes().AsParallel()
    let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
    where attributes != null && attributes.Length > 0
    select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };
97
ответ дан casperOne 24 October 2018 в 10:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: