繁体   English   中英

C# - 更快地获取设置公共静态字段而不是使用 Reflection.SetValue / GetValue

[英]C# - Faster way to get set public static fields instead of using Reflection.SetValue / GetValue

我有一个场景,我需要在运行时更改公共静态字段。 我知道我可以通过如下反射来设置我想要的公共静态字段,但它真的很慢。

string typeName = "ABC";
string fieldName = "IsA";

Type.GetType(typeName ).GetField(fieldName ).SetValue(null, value);

var value = Type.GetType(typeName ).GetField(fieldName ).GetValue(null);

我想知道有没有更快的访问方式,例如使用 Reflection.Emit、Linq.Expression 或其他方法。 据我所知,目前他们中的大多数只支持带有实例的字段。

您可以为此使用表达式。 你基本上有三个选择:

  1. 反射。 减缓。
  2. 动态编译表达式。 快速地。
  3. 类型化编译表达式。 超级快。

在您的情况下,使用类型表达式有点棘手。 我想我们不能假设所有静态属性都是string类型? 第二个选项允许您轻松地为任何字段类型创建快速设置器。

请注意,在编译表达式时,您必须为已编译的委托维护一个缓存 编译步骤非常昂贵!

class Program
{
    public class Foo
    {
        public static string Name;
    }

    public static void Main()
    {
        var delegateCache = new Dictionary<(string, string), Delegate>();
        
        var typeName = typeof(Foo).FullName;
        var fieldName = "Name";

        var key = (typeName, fieldName);

        // Caching is crucial!
        if (!delegateCache.TryGetValue(key, out var d))
        {
            d = CreateStaticSetter(typeName, fieldName);
            delegateCache.Add(key, d);
        }

        // For a strongly typed delegate, we would use Invoke() instead.
        d.DynamicInvoke("new value");

        Console.WriteLine(Foo.Name);
    }

    private static Delegate CreateStaticSetter(string typeName, string fieldName)
    {
        var type = Type.GetType(typeName) ?? throw new ArgumentException();
        var field = type.GetField(fieldName) ?? throw new ArgumentException();
        
        var valueExp = Expression.Parameter(field.FieldType, "value");
        var fieldExp = Expression.Field(null, field);
        var assignExp = Expression.Assign(fieldExp, valueExp);

        // TODO: Can be further optimized with a strongly typed delegate.
        var expr = Expression.Lambda(assignExp, valueExp);
        return expr.Compile();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM