gpt4 book ai didi

c# - 通过表达式树从嵌套类中获取静态字段

转载 作者:行者123 更新时间:2023-11-30 21:47:57 25 4
gpt4 key购买 nike

我有这些类(class):

public class Entity
{
public static readonly EntitySchema Schema = new EntitySchema();
}

public abstract class BaseSchema
{
public abstract string Name {get;}
}

public class EntitySchema : BaseSchema
{
public override string Name => "Schema";
}

现在,我想通过一个方法访问 EntitySchema.Name,该方法对实体一无所知(无法访问静态字段)。

我可以通过反射(reflection)来做到这一点:

static BaseSchema GetSchema<T>()
{
var pr = typeof(T).GetField("Schema");
var schema = pr.GetValue(null);
return schema as BaseSchema;
}

但与直接调用 Entity.Schema.Name 相比,反射版本慢 50 倍

有没有办法将反射版本转换为表达式树并预编译调用?

最佳答案

当然可以,但是 .NET 需要完整的字段定义(在本例中为 EntitySchema global::Entity.Schema)才能获得实际值。反射(reflection)让你得到这个定义。您需要为每种类型创建一个委托(delegate),即:

public static class SchemaGetter
{
private static readonly Dictionary<object, Func<BaseSchema>> _lookup = new Dictionary<object, Func<BaseSchema>>();

public static BaseSchema Get<T>()
{
Func<BaseSchema> action;

if(!_lookup.TryGetValue(typeof(T), out action))
{
action = MakeDelegate<T>();

_lookup.Add(typeof(T), action);
}

return action();
}

private static Func<BaseSchema> MakeDelegate<T>()
{
// We did this before already...

FieldInfo field = typeof(T).GetField("Schema", BindingFlags.Public | BindingFlags.Static);
var fieldExpression = Expression.Field(null, field);

var lambda = Expression.Lambda<Func<BaseSchema>>(fieldExpression);

return lambda.Compile();
}
}

其次是 BaseSchema schema = SchemaGetter.Get<Entity>()获取实际架构。

也许它足以缓存您从初始 GetSchema<T>() 获得的结果实现(将其包装在字典查找中)。我认为在这种情况下必须如此,因为无论如何该字段都是静态的。

关于c# - 通过表达式树从嵌套类中获取静态字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38027266/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com