繁体   English   中英

为什么我不能通过dynamic关键字访问从函数返回的匿名类型的属性?

[英]Why can't I access properties of an anonymous type returned from a function via the dynamic keyword?

我有一个函数返回一个像这样的匿名类型(简化为说明目的)...

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'的定义

是什么赋予了? 我在这里错过了什么?

问题是匿名类型是内部的 ,这意味着您无法使用dynamic属性访问器从其创建的项目以外的项目访问其属性。动态绑定将它们视为它知道的最接近的公共继承类型 - object

要解决此问题,您可以声明一个公共类型来表示您希望在匿名类型中找到的值。 无论如何,这可能是一个好主意,因为您显然希望在代码的其他部分使用返回的属性。 使用声明的类型还可以使您保持类型安全,从而完全不需要dynamic

如果你绝对必须在这里使用dynamic ,那么下一个最佳选择可能是更改你的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

小提琴演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM