Установка / получение полей класса с массивом: быстрее, чем отражение? - PullRequest
0 голосов
/ 13 марта 2019

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

При доступе изнутри (см. Метод Calculate) я хочу использовать поля по имени для лучшей читаемости. Количество полей варьируется между различными классами, полученными из Operation.

Есть ли более быстрый способ сделать это, чем с помощью отражения?

public abstract class Operation
{
    readonly FieldInfo[] inputFields;

    public int InputCount {get {return inputFields.Length;}}

    public Cacheable[] InputData
    {
        get 
        {
            Cacheable[] result = new Cacheable[inputFields.Length];

            for (int i=0; i<inputFields.Length; i++)
            {
                result[i] = (Cacheable)inputFields[i].GetValue(this);
            }

            return result;
        }
        set 
        {
            for (int i=0; i<inputFields.Length; i++)
            {
                inputFields[i].SetValue(this, value[i]);
            }
        }
    }

    public Operation()
    {
        FieldInfo[] inputFields = GetType().GetFields();
    }

    public abstract void Calculate();
}

public class OperationA: Operation
{
    public CacheableU SomeField;
    public CacheableV AnotherField;

    public override void Calculate()
    {
        DoSomething(SomeField, AnotherField);
    }
}   

public class OperationB: Operation
{
    public CacheableU SomeField;
    public CacheableV AnotherField;
    public CacheableW YetAnotherField;

    public override void Calculate()
    {
        DoSomethingElse(SomeField, AnotherField, YetAnotherField);
    }
}

// ...
Cacheable[] inputsToA = new[]{c1, c2};
OperationA opa = new OperationA();
opa.InputData = inputsToA;
opa.Calculate();

Cacheable[] inputsToB = new[]{c3, c4, c5};
OperationB opb = new OperationB();
opb.InputData = inputsToB;
opb.Calculate();

1 Ответ

3 голосов
/ 13 марта 2019

Краткий ответ: Да.

Более длинный ответ: зависит. Как часто это делается? Если это делается много-много раз за время жизни приложения, то есть более быстрые способы, чем рефлексия: либо используйте для этого деревья выражений (https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/expression-trees/)), либо выделите IL во время выполнения.

Однако стоимость составления дерева выражений (или функции IL) для повторного использования довольно высока. Если вы делаете это один раз в начале жизненного цикла приложения, или если домен приложения является недолговечным (например, консольное приложение, которое запускается каждые несколько минут), то затраты на доступ значительно уменьшаются из-за затрат на запуск.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...