Что состоит в том, чтобы определить лучший способ, и доступ выбрал свойства в C#?

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

Scott Mitchell записал всестороннее учебное руководство при реализации того шаблона:
Оптимистичный параллелизм Реализации

7
задан Community 23 May 2017 в 12:04
поделиться

2 ответа

Лямбды отлично подходят для многих сценариев, но если они вам не нужны, может быть, просто не используйте их? Ненавижу это говорить, но простые строки проверены и протестированы, особенно для таких сценариев, как привязка данных. Если вам нужен быстрый доступ, вы можете посмотреть HyperDescriptor, или существуют способы компиляции делегата для методов доступа к свойствам, или вы можете построить Expression из строки и скомпилировать его (включая приведение к ] объект , если вам нужна известная подпись, вместо вызова (гораздо более медленного) DynamicInvoke ).

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

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


Другая мысль; если вы используете Expression , вы можете сделать что-то вроде:

public void IncludeProperties<T>(
    Expression<Func<T,object>> selectedProperties)
{
    // some logic to store parameter   
}

IncludeProperties<IUser>( u => new { u.ID, u.LogOnName, u.HashedPassword });

, а затем разобрать выражение? По крайней мере, немного аккуратнее ... вот пример кода, показывающий деконструкцию:

public static void IncludeProperties<T>(
    Expression<Func<T, object>> selectedProperties)
{
    NewExpression ne = selectedProperties.Body as NewExpression;
    if (ne == null) throw new InvalidOperationException(
          "Object constructor expected");

    foreach (Expression arg in ne.Arguments)
    {
        MemberExpression me = arg as MemberExpression;
        if (me == null || me.Expression != selectedProperties.Parameters[0])
            throw new InvalidOperationException(
                "Object constructor argument should be a direct member");
        Console.WriteLine("Accessing: " + me.Member.Name);
    }
}
static void Main()
{
    IncludeProperties<IUser>(u => new { u.ID, u.LogOnName, u.HashedPassword });
}

Как только вы узнаете MemberInfo ( me.Member выше), создайте свой собственный лямбды для индивидуального доступа должны быть тривиальными. Например (включая приведение к объекту , чтобы получить единую подпись):

var param = Expression.Parameter(typeof(T), "x");
var memberAccess = Expression.MakeMemberAccess(param, me.Member);
var body = Expression.Convert(memberAccess, typeof(object));
var lambda = Expression.Lambda<Func<T, object>>(body, param);
var func = lambda.Compile();
9
ответ дан 7 December 2019 в 01:23
поделиться

Вот самое короткое выражение, которое я могу придумать:

public static void IncludeProperties(Expression<Action<IUser>> selectedProperties)
{
    // some logic to store parameter   
}

public static void S(params object[] props)
{
    // dummy method to get to the params syntax
}

[Test]
public void ParamsTest()
{
    IncludeProperties(u => S(
        u.Id,
        u.Name
        ));

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

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