Кто-либо знает быстрый способ добраться до пользовательских атрибутов на перечислении значений?

Вот как ваше регулярное выражение соответствует no and little risk:

Одна из ветвей вашего регулярного выражения - ...|(?<!\bno)(?<!low).+risk.

Механизм регулярных выражений запускается попыткой сопоставления в каждой позиции в целевой строке, начиная с начала:

no and little risk
^

Первое ограничение заключается в том, что текущей позиции не может предшествовать граница слова, за которой следует «нет» (из-за (?<!\bno)). Это условие выполняется: началу строки назначения ничего не предшествует.

Вторым ограничением является то, что текущей позиции не может предшествовать «низкий» (из-за (?<!low)). Это условие также выполняется (см. Выше).

Затем мы сопоставляем один или несколько не-новых символов, но как можно больше из них (это часть .+). Здесь мы первоначально потребляем всю строку:

no and little risk
------------------^

Но затем регулярное выражение требует совпадения risk, что не удается (в целевой строке больше не осталось символов). Это заставляет .+ возвращаться назад и потреблять все меньше и меньше символов, пока это не произойдет:

no and little risk
--------------^

На этом этапе risk успешно совпадает, и регулярное выражение заканчивается.

Основная проблема в том, что вы хотите сделать, это (?<!\bno.+)(?<!low.+)risk, но то, что вы написали, это (?<!\bno)(?<!low).+risk. Это две совершенно разные вещи!

Первая означает «соответствовать« риску », но только если ей не предшествуют« нет »или« низкий уровень »где-либо в строке (до 1 символа до« риска ») ». Последнее означает «соответствовать любой непустой подстроке, за которой следует« риск », если ей не предшествует ни« нет », ни« низкий »». Это дает механизму регулярных выражений свободу поиска любой подходящей позиции в строке, если ей не предшествует сразу «нет» или «низкий уровень» и где-то следует «. + Риск».

К сожалению, (?<!\bno.+) не является допустимым регулярным выражением, потому что контрольные утверждения должны иметь фиксированную длину.

Один из возможных обходных путей - сделать следующее:

^(?!.*(?:\bno|low).+risk).*risk

Это говорит: начиная с начала строки, сначала убедитесь, что нет «нет» или «низкий», а затем «риск» в любом месте, затем сопоставьте «риск» в любом месте строки.

Это не совсем эквивалентно (гипотетической) версии с изменяющейся шириной, потому что она соответствовала бы

risk no risk
^^^^

из-за присутствия «риска» без «нет», предшествующего ему. тогда как этот обходной путь сначала находит

risk no risk
     ^^^^^^^

и немедленно отклоняет всю строку.

18
задан Keith 20 August 2008 в 11:34
поделиться

2 ответа

Это - вероятно, самый легкий путь.

А более быстрый путь состоял бы в том, чтобы Статически Испустить код IL с помощью Динамического Метода и ILGenerator. Хотя я только привык это для GetPropertyInfo, но не вижу, почему Вы не могли испустить CustomAttributeInfo также.

, Например, код для испускания метода get от свойства

public delegate object FastPropertyGetHandler(object target);    

private static void EmitBoxIfNeeded(ILGenerator ilGenerator, System.Type type)
{
    if (type.IsValueType)
    {
        ilGenerator.Emit(OpCodes.Box, type);
    }
}

public static FastPropertyGetHandler GetPropertyGetter(PropertyInfo propInfo)
{
    // generates a dynamic method to generate a FastPropertyGetHandler delegate
    DynamicMethod dynamicMethod =
        new DynamicMethod(
            string.Empty, 
            typeof (object), 
            new Type[] { typeof (object) },
            propInfo.DeclaringType.Module);

    ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
    // loads the object into the stack
    ilGenerator.Emit(OpCodes.Ldarg_0);
    // calls the getter
    ilGenerator.EmitCall(OpCodes.Callvirt, propInfo.GetGetMethod(), null);
    // creates code for handling the return value
    EmitBoxIfNeeded(ilGenerator, propInfo.PropertyType);
    // returns the value to the caller
    ilGenerator.Emit(OpCodes.Ret);
    // converts the DynamicMethod to a FastPropertyGetHandler delegate
    // to get the property
    FastPropertyGetHandler getter =
        (FastPropertyGetHandler) 
        dynamicMethod.CreateDelegate(typeof(FastPropertyGetHandler));


    return getter;
}
10
ответ дан 30 November 2019 в 09:11
поделиться

Я обычно нахожу, что отражение довольно быстро, пока Вы динамично не вызываете методы.
, Так как Вы просто читаете Атрибуты перечисления, Ваш подход должен работать просто великолепно без любого реального хита производительности.

И помнят, что обычно необходимо пытаться сохранить вещи простыми понять. По разработке это только для получения некоторых мс не мог бы стоить того.

7
ответ дан 30 November 2019 в 09:11
поделиться
Другие вопросы по тегам:

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