Какой-либо способ избежать Свойства встраивает оптимизацию в C#?

Вам, кажется, нужна условная агрегация:

SELECT
    OrderID,
    MAX(CASE WHEN item = 'apple' THEN weight END) Apple,
    MAX(CASE WHEN item = 'banana' THEN weight END) Banana,
    MAX(CASE WHEN item = 'orange' THEN weight END) Orange,
    MAX(CASE WHEN item = 'grape' THEN weight END) Grape
    Location
FROM samples
GROUP BY OrderID, Location
7
задан Brian Genisio 17 February 2009 в 16:32
поделиться

4 ответа

Используя стек здесь является медленным и ненужным; я просто использовал бы:

get { return GetProperty<int>("Foo"); }
set { SetProperty("Foo", value); }

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

Другая альтернатива является объектным ключом (используйте ссылочное равенство для сравнения) - много из ComponentModel прокладывает себе путь, также, как и некоторые свойства в WF/WPF:

static readonly object FooKey = new object();
...
get { return GetProperty<int>(FooKey); }
set { SetProperty(FooKey, value); }

Конечно, Вы могли объявить тип для ключей (с a Name свойство), и использование, что:

static readonly PropertyKey FooKey = new PropertyKey("Foo");

и т.д.; однако, для ответа на вопрос: отметьте его (но не делайте этого) с:

[MethodImpl(MethodImplOptions.NoInlining)]

или

[MethodImpl(MethodImplOptions.NoOptimization)]

или

[MethodImpl(MethodImplAttributes.NoOptimization
    | MethodImplAttributes.NoInlining)]

14
ответ дан 6 December 2019 в 09:23
поделиться

Используя стек не хорошая идея. Вы полагаетесь на внутреннюю реализацию компилятора для искусственного связывания набора свойств к свойствам языка.

  1. наличие требования для добавления MethodImpl атрибут делает использование Вашего набора свойств непрозрачным для других разработчиков.
  2. даже если набор свойств имеет MethodImpl атрибут, ничто не гарантирует Вам, это будет первый кадр на стеке вызовов. Возможно, что блок был оснащен или изменен для введения вызовов между фактическим свойством и вызова к набору свойств. (Думайте программирование аспекта),
  3. Новые языки или даже будущая версия компилятора C# могли бы украсить средства доступа свойства по-другому затем '_get' и '_set'
  4. Построение стека вызовов является относительно медленной операцией, поскольку это требует, чтобы внутренний сжатый стек был распакован и название каждого типа и метода, который будет получен с помощью отражения.

Необходимо действительно просто реализовать средства доступа набора свойств для взятия параметра для идентификации свойства - любой имя строки (как Hastable) или объект (как набор свойств зависимости WPF)

2
ответ дан 6 December 2019 в 09:23
поделиться

Можно попытаться создать файл шаблона T4, таким образом, свойства могли быть автоматически сгенерированы с корректными названиями свойства GetProperty () и SetProperty () методы.

T4: текстовый шаблонный инструментарий преобразования T4 (текстовый шаблонный инструментарий преобразования) генерация кода - содержащийся в полном порядке секрет Visual Studio

1
ответ дан 6 December 2019 в 09:23
поделиться

Если Вы хотите избежать трудно кодированных строк, можно использовать:

protected T GetProperty<T>(MethodBase getMethod)
{
    if (!getMethod.Name.StartsWith("get_")
    {
        throw new ArgumentException(
            "GetProperty must be called from a property");
    }
    return GetValue<T>(getMethod.Name.Substring(4));
}

Добавьте больше исправности, проверяющей, как Вы считаете целесообразным

затем свойством становятся

public int Foo
{
    get { return GetProperty<int>(MethodInfo.GetCurrentMethod()); }     
}

наборы изменяются таким же образом.

GetCurrentMethod () также пересекает стек, но делает так через (внутреннее) неуправляемое доверие вызова маркерам стека, так будет работать в режиме выпуска также.

Кроме того, для быстрого исправления [MethodImpl] с MethodImplAttributes. NoOptimization) или MethodImplAttributes. NoInlining будет также работать, хотя с хитом производительности (хотя, учитывая, что Вы пересекаете стековый фрейм каждый раз, этот хит незначителен).

Дальнейшая техника, получая некоторый уровень времени компиляции, проверяя:

public class PropertyHelper<T>
{
    public PropertyInfo GetPropertyValue<TValue>(
        Expression<Func<T, TValue>> selector)
    {
        Expression body = selector;
        if (body is LambdaExpression)
        {
            body = ((LambdaExpression)body).Body;
        }
        switch (body.NodeType)
        {
            case ExpressionType.MemberAccess:
                return GetValue<TValue>(
                    ((PropertyInfo)((MemberExpression)body).Member).Name);
            default:
                throw new InvalidOperationException();
        }
    }
}

private static readonly PropertyHelper<Xxxx> propertyHelper 
    = new PropertyHelper<Xxxx>();

public int Foo
{
    get { return propertyHelper.GetPropertyValue(x => x.Foo); }     
}

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

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

1
ответ дан 6 December 2019 в 09:23
поделиться
Другие вопросы по тегам:

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