dynamic关键字与ExpandoObject一起附加和删除属性
本文关键字:删除 属性 一起 关键字 ExpandoObject dynamic | 更新日期: 2023-09-27 18:01:07
我知道现在在C#3.0中,我们可以使用dynamic关键字在运行时添加/删除属性,比如Object作为通用容器的JavaScript概念,但我有一个问题。
它真的扩展了我想要的类型的对象吗??
例如:我们有班级:
class Person
{
public string Name { get; set; }
public int Age { get; set;}
}
我将从Person类创建一个新对象:
dynamic p = new ExpandoObject();
这个对象真的是Person类的对象吗?它不再与Person类相关了??
Console.WriteLine(p.GetType()); // System.Dynamic.ExpandoObject
现在我将为属性设置值,并用新属性"Foo"扩展对象p:
p.Age = 25;
p.Foo = "foo";
我附加了新的属性"Foo",并为属性"Age"设置了值,但我为System.Dynamic.ExpandoObject
类型的对象而不是Person
类型的对象这样做,所以我在这部分不匹配,我真的从我需要的类型扩展了对象吗,我可以使用强制转换来指代这样的对象类型吗:
Console.WriteLine(((Person)p).Name);
类型为的未处理异常中出现"Microsoft.CSharp.RuntimeBinder.RuntimeBinderException"System.Core.dll
我认为您混淆了这里的强制转换和转换问题。
-
铸造:更改指向一个物体。向上或向下移动对象层次结构,或移动到实现接口
-
转换:从的原始源对象创建新对象一个不同的类型,并通过对该类型的引用来访问它。
通常很难知道C#
中的2之间的区别,因为它们都使用相同的C#
运算符:强制转换。
在这种情况下,你几乎肯定不是在寻找一个铸造操作。将一个动态转换为另一个动态本质上是身份转换。它没有提供任何价值,因为您只是获得了对同一底层对象的动态引用。由此产生的查找也不会有什么不同。
相反,在这种情况下,您似乎想要的是转换。这就是将底层对象变形为不同的类型,并以动态方式访问生成的对象。最好的API是Convert.ChangeType
。
public static dynamic Convert(dynamic source, Type dest) {
return Convert.ChangeType(source, dest);
}
在这种情况下,而不是:
Console.WriteLine(((Person)p).Name);
尝试:
Console.WriteLine(ConvertTo<Person>(p).Name);
如果你愿意,我可以写ConvertTo<T>
声明并在这里解释。
您不能像这样从动态类型强制转换为实体类型,因为该类型当时与动态无关,只是看起来像它,因为它具有类似的属性。
但是,您可以序列化动态实例,然后将其反序列化为您所拥有的实体类型。我不知道你为什么要这么做。。。