我有一个返回匿名类型的函数(为简化说明而简化)...
public object GetPropertyInfo()
{
return new {
PropertyName = "Foo",
Value = "Laa"
};
}
当我这样做时......
dynamic pi = GetPropertyInfo();
Console.WriteLine(pi);
它输出这个(就像我在直接窗口中做'?pi'一样)......
{ PropertyName = "A", Value = 44 }
PropertyName: "A"
Value: 44
但如果我尝试这样做......
string propertyName = pi.PropertyName;
...它编译但抛出运行时异常说
抛出异常:System.Core.dll中的“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”
附加信息:'object'不包含'PropertyName'的定义
是什么给出的?我在这里缺少什么?
答案 0 :(得分:10)
问题在于anonymous types are internal,这意味着您无法使用dynamic
属性访问者从其创建的项目以外的项目访问其属性。动态绑定将它们视为它知道的最近的公共继承类型 - object
。
要解决此问题,您可以声明一个公共类型来表示您希望在匿名类型中找到的值。无论如何,这可能是一个好主意,因为您显然希望在代码的其他部分使用返回的属性。使用声明的类型还可以保持类型安全,从而完全不需要dynamic
。
如果您绝对必须在此使用dynamic
,则下一个最佳选择可能是更改您的AssemblyInfo.cs
文件,以使您可以访问项目的内部属性。重新尝试从以下位置访问它们:
[assembly:InternalsVisibleTo("MyOtherProject")]
答案 1 :(得分:2)
修改强>
根据你的编辑。显然您根本不需要动态,因为没有动态属性。只需使用预定义属性创建具体类型即可。无论如何,最好避免动态。
旧答案
您需要使用ExpandoObject
。参考here。
事实上,GetPropertyInfo()
应该返回ExpandoObject
。
dynamic foo = this.GetPropertyInfo();
string i = foo.MyPropertyName;
private ExpandoObject GetPropertyInfo()
{
dynamic obj = new ExpandoObject();
obj.PropertyName = "MyPropertyName";
obj.PropertyType = "MyPropertyType";
return obj;
}
ExpandoObject类使您可以添加和删除其成员 运行时的实例,以及设置和获取这些成员的值。 此类支持动态绑定,使您可以使用标准 语法如sampleObject.sampleMember而不是更复杂的语法 像sampleObject.GetAttribute(" sampleMember")。
答案 2 :(得分:1)
此外,您可以使用System.Reflection
object D = GetPropertyInfo();
Type t = D.GetType(); // get object's type
PropertyInfo p = t.GetProperty("PropertyName"); // look up for the property:
object P = p.GetValue(D, null); // get the value