C# 在不重新解析通向成员的路径的情况下对成员进行动态评估

C# 在不重新解析通向成员的路径的情况下对成员进行动态评估,c#,dynamic,C#,Dynamic,尽管我通常更喜欢提出一个理论问题,然后再举一个例子,但我会用一个例子来解释这种情况,因为我不知道从哪里开始(问题以粗体突出显示): 假设我有一个对象(我们叫他FatOne),它有很多属性、字段、机制等,我想经常从中获得以下“链接”属性: myFatOne.RootProperty1.OneLevelDeep1.TwoLevelDeepA; myFatOne.RootProperty1.OneLevelDeep2.TwoLevelDeepB; myFatOne.RootProperty2.OneL

尽管我通常更喜欢提出一个理论问题,然后再举一个例子,但我会用一个例子来解释这种情况,因为我不知道从哪里开始(问题以粗体突出显示):

假设我有一个对象(我们叫他
FatOne
),它有很多属性、字段、机制等,我想经常从中获得以下“链接”属性:

myFatOne.RootProperty1.OneLevelDeep1.TwoLevelDeepA;
myFatOne.RootProperty1.OneLevelDeep2.TwoLevelDeepB;
myFatOne.RootProperty2.OneLevelDeep;
但是,评估
OneLevelDeep2
RootProperty2
的成本确实很高。出于这个问题的考虑,我不能缓存它们。我想创建一个更轻的对象(当然称为
LiteOne
),它将包含以下成员(请注意,我使用的是'members',而不是方法、字段或属性,因为这就是问题所在。)

当然,当我调用
myLiteOne.Member1
时,我不需要缓存值,我需要最后一级的求值(
TwoLevelDeepA
用于
Member1
,而无需解析整个“链”(即:
RootProperty1.OneLevelDeep1
用于
Member1
),我该怎么做? (我觉得这件事很简单,我现在只是在放屁。)

想法1,玩指针。我不确定我是否想采用不安全的方式,我确定有更好的解决方案

想法2,享受Func()带来的乐趣。例如,如果
Member1
是Func,我可以这样做:

var tmp = myFatOne.RootProperty1.OneLevelDeep1;
myLiteOne.Member1 = new Func<T>(() => tmp.TwoLevelDeepA);
var tmp=myFatOne.RootProperty1.OneLevelDeep1;
myLiteOne.Member1=新函数(()=>tmp.TwoLevelDeepA);
如果我需要
Member1
作为属性,我可以创建一个名为
\u Member1
的底层方法(而不是字段),并用
Member1
属性将其包装起来

想法3,在
LiteOne
上有基础字段
LiteOne
可以有3个基本字段,类型分别为
typeof(myFatOne.RootProperty1.OneLevelDeep1)
typeof(myFatOne.RootProperty1.OneLevelDeep2)
typeof(myFatOne.RootProperty2)
成员1
包装,
Member2
Member3
属性,分别获得
TwoLevelDeepA
TwoLevelDeepB
OneLevelDeeph
成员。但是,如果基础字段中有一个是不可变的,我认为这会导致一个问题


还有其他(更好的)想法吗?

所以你不想缓存这些值,甚至不想计算它们?您认为使用指针、Func或PropertyInfo等如何降低成本?如果不缓存需要计算的值,可以使用DynamicMethod生成属性get方法,并使用/cache这些方法访问目标属性。使用DynamicMethod需要IL知识,除非您使用像Fasterflect这样的库-请参阅PS:您可能需要缓存委托列表(动态方法)来访问深度嵌套的属性。
var tmp = myFatOne.RootProperty1.OneLevelDeep1;
myLiteOne.Member1 = new Func<T>(() => tmp.TwoLevelDeepA);