- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 expando 对象,我正在尝试定义一个计算属性。
我知道我可以通过执行以下操作来定义一个简单的属性:
dynamic myExpando = new ExpandoObject();
myExpando.TheAnswerToLifeTheUniverseAndEverything= 42;
同样,我也可以定义一个方法:
myExpando.GetTheQuestion = ((Func<string>)(() =>
{
return "How many road must a man walk down before we can call him a man?";
}));
在使用标准对象时,我们可以定义一个计算属性,即定义一个将返回自定义方法/计算结果的属性。无需示例。
我需要在我的 expando 上做一些类似的事情——拥有一个实际调用“Func”的属性(或其他形式的委托(delegate),只要我可以调用自定义方法并具有自定义返回类型,任何事情都会发生)。所以基本上我需要调用第二个示例中的方法,但让它像属性一样工作。
基本上,我需要能够使用 myExpando.GetTheQuestion 而不是 myExpando.GetTheQuestion() 来调用它,同时保持将自定义委托(delegate)定义为属性的能力 body 。
有没有办法做到这一点?我相信我可以通过使用表达式树来做到这一点,但我承认我在那里有点迷路。谁能就如何实现这一目标提供一些指导??
编辑
做了更多的研究。除非有一些我不知道的非常具体的类/接口(interface)/语法,否则我开始认为以上是不可能的。据我所知,ExpandoObject 类通过定义一些执行后台管道的方法来工作 - TryGetMember、TrySetMember 等。现在,当在动态对象上“访问属性”时,TryGetMember 是被调用的成员。该成员从某种内部字典返回一个值(是的,我知道......这有点简化但应该给出想法)......没有对返回值的类型进行测试。这意味着在我的示例中 myExpando.GetTheQuestion 将返回原始 Func。
看来,由于 TryGetMember 只是返回一个值,因此没有办法让它“执行”属性代码。为此,您需要某种表达式/lambda/func/action 代理,哪个值实际上是方法的结果。这似乎是不可能的(也没有多大意义,除非我错过了什么——基本上你会有一个设置为“委托(delegate)”的值,然后作为委托(delegate)返回值获取???)。我是正确的还是这个或者我遗漏了什么?
最佳答案
您需要通过继承 DynamicObject
来创建自己的 ExpandoObject并覆盖
public override bool TryGetMember(GetMemberBinder binder, out object result)
和 public override bool TrySetMember(SetMemberBinder binder, object value)
实现 TrySetMember
将值存储在私有(private) Dictionary<string,object>
中在 binder.Name
下并使用 TryGetMember
从该字典中检索它,这将为您提供一个基本的 ExpandoObject。然后给它你需要的功能,添加检查 TryGetMember
, 拉动物体后,看它是否is Delagate
然后使用反射来查看它是否不接受任何参数。如果两者都为真,则转换为 dynamic
并且不添加 arg 调用括号并将其分配给 result
.
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (_dictionary.TryGetValue(binder.Name, out result)){
if(result is Delegate && /* some reflection check on args*/){
result = ((dynamic)result)();
}
}
}
我有一个开源框架 ImpromptuInterface(在 nuget 中),它有一个非密封 ImpromptuDictionary
您可以从 ExpandoObject
开始相反,特别是如果您需要 ExpandoObject
的任何更细微的功能时例如 gui 绑定(bind)支持。它还有更多 dlr plumbing features你可能会觉得有用。
关于c# - 在 expando 对象上定义计算属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14816391/
你能比较一下属性吗 我想禁用文本框“txtName”。有两种方式 使用javascript,txtName.disabled = true 使用 ASP.NET, 哪种方法更好,为什么? 最佳答案 我
Count 属性 返回一个集合或 Dictionary 对象包含的项目数。只读。 object.Count object 可以是“应用于”列表中列出的任何集合或对
CompareMode 属性 设置并返回在 Dictionary 对象中比较字符串关键字的比较模式。 object.CompareMode[ = compare] 参数
Column 属性 只读属性,返回 TextStream 文件中当前字符位置的列号。 object.Column object 通常是 TextStream 对象的名称。
AvailableSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。 object.AvailableSpace object 应为 Drive 
Attributes 属性 设置或返回文件或文件夹的属性。可读写或只读(与属性有关)。 object.Attributes [= newattributes] 参数 object
AtEndOfStream 属性 如果文件指针位于 TextStream 文件末,则返回 True;否则如果不为只读则返回 False。 object.A
AtEndOfLine 属性 TextStream 文件中,如果文件指针指向行末标记,就返回 True;否则如果不是只读则返回 False。 object.AtEn
RootFolder 属性 返回一个 Folder 对象,表示指定驱动器的根文件夹。只读。 object.RootFolder object 应为 Dr
Path 属性 返回指定文件、文件夹或驱动器的路径。 object.Path object 应为 File、Folder 或 Drive 对象的名称。 说明 对于驱动器,路径不包含根目录。
ParentFolder 属性 返回指定文件或文件夹的父文件夹。只读。 object.ParentFolder object 应为 File 或 Folder 对象的名称。 说明 以下代码
Name 属性 设置或返回指定的文件或文件夹的名称。可读写。 object.Name [= newname] 参数 object 必选项。应为 File 或&
Line 属性 只读属性,返回 TextStream 文件中的当前行号。 object.Line object 通常是 TextStream 对象的名称。 说明 文件刚
Key 属性 在 Dictionary 对象中设置 key。 object.Key(key) = newkey 参数 object 必选项。通常是 Dictionary 
Item 属性 设置或返回 Dictionary 对象中指定的 key 对应的 item,或返回集合中基于指定的 key 的&
IsRootFolder 属性 如果指定的文件夹是根文件夹,返回 True;否则返回 False。 object.IsRootFolder object 应为&n
IsReady 属性 如果指定的驱动器就绪,返回 True;否则返回 False。 object.IsReady object 应为 Drive&nbs
FreeSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。只读。 object.FreeSpace object 应为 Drive 对象的名称。
FileSystem 属性 返回指定的驱动器使用的文件系统的类型。 object.FileSystem object 应为 Drive 对象的名称。 说明 可
Files 属性 返回由指定文件夹中所有 File 对象(包括隐藏文件和系统文件)组成的 Files 集合。 object.Files object&n
我是一名优秀的程序员,十分优秀!