为什么我不能通过dynamic关键字访问从函数返回的匿名类型的属性?
本文关键字:返回 类型 属性 函数 不能 dynamic 访问 关键字 为什么 | 更新日期: 2023-09-27 18:06:12
我有一个函数,它返回一个匿名类型,如下所示(为了便于说明而简化)…
public object GetPropertyInfo()
{
return new {
PropertyName = "Foo",
Value = "Laa"
};
}
当我这样做的时候…
dynamic pi = GetPropertyInfo();
Console.WriteLine(pi);
它输出这个(如果我做'?
{ PropertyName = "A", Value = 44 }
PropertyName: "A"
Value: 44
但是如果我尝试这样做…
string propertyName = pi.PropertyName;
…它编译,但抛出一个运行时异常,说
抛出异常:'Microsoft.CSharp.RuntimeBinder. 'RuntimeBinderException' in System.Core.dll
附加信息:'object'不包含'PropertyName'的定义
给了什么?我遗漏了什么?
问题是匿名类型是内部的,这意味着您不能使用dynamic
属性访问器从其他项目访问它们的属性,而不是创建它们的项目。动态绑定将它们视为它所知道的最接近的公共继承类型——object
。
要解决这个问题,可以声明一个公共类型来表示您希望在匿名类型中找到的值。无论如何,这可能是个好主意,因为您显然希望在代码的其他部分使用返回的属性。使用声明的类型还使您能够维护类型安全,从而完全避免了对dynamic
的需要。
如果你绝对必须在这里使用dynamic
s,下一个最好的选择可能是改变你的AssemblyInfo.cs
文件,使内部属性可以访问到你试图访问它们的项目:
[assembly:InternalsVisibleTo("MyOtherProject")]
编辑
根据你的编辑。显然根本不需要动态,因为没有动态属性。只需用预定义的属性创建一个具体类型。无论如何,最好尽可能避免动态。
老回答您需要使用ExpandoObject
。参考这里。
实际上,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")。
也可以使用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
小提琴演示