使用数组设置/获取类的字段:比反射更快的方法吗?

时间:2019-03-13 18:25:43

标签: c# reflection

当我从外部访问我的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 个答案:

答案 0 :(得分:3)

简短的回答:是的。

更长的答案:这取决于。多久执行一次?如果在应用程序的生命周期中要完成很多次操作,那么有比反射更快的方法:使用表达式树(https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/expression-trees/)或在运行时发出IL来实现。

但是,编译表达式树(或IL函数)以供重用的成本相当高。如果您是在应用程序生命周期的开始时执行一次此操作,或者如果appdomain寿命很短(例如,每隔几分钟运行一次的控制台应用程序),那么每次访问的成本将与启动成本相比相形见