[英]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 或其他方法。 據我所知,目前他們中的大多數只支持帶有實例的字段。
您可以為此使用表達式。 你基本上有三個選擇:
在您的情況下,使用類型表達式有點棘手。 我想我們不能假設所有靜態屬性都是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.