带有 ExpandoObject 的动态关键字附加和删除属性
dynamic keyword with ExpandoObject to attach and remove properties
我知道现在在 C# 3.0 中我们可以在 运行 时间内对 add/remove 属性使用动态关键字,就像对象作为通用容器的 JavaScript 概念一样,但我有一个问题。
真的展开我想要的类型的对象吗??
例如:
我们有 class:
class Person
{
public string Name { get; set; }
public int Age { get; set;}
}
我将从 Person 创建一个新对象 Class:
dynamic p = new ExpandoObject();
现在这个对象真的是 class Person 的对象吗?它不再与 Person class 相关了??
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);
An unhandled exception of type
'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in
System.Core.dll
您不能像这样从动态类型转换为实体类型,因为当时该类型与动态类型没有任何关系,只是看起来像它,因为它具有相似的属性。
但是,您可以序列化动态实例,然后将其反序列化为您拥有的实体类型。我不确定你为什么要这样做...
我认为你在这里混淆了转换和转换的问题。
转换:改变指向的引用类型的行为
一个东西。向上或向下移动对象层次结构或移动到
实现接口
Converting: 从原始源对象创建新对象
不同的类型并通过对该类型的引用访问它。
通常很难知道 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>
声明并在这里解释。
我知道现在在 C# 3.0 中我们可以在 运行 时间内对 add/remove 属性使用动态关键字,就像对象作为通用容器的 JavaScript 概念一样,但我有一个问题。
真的展开我想要的类型的对象吗??
例如: 我们有 class:
class Person
{
public string Name { get; set; }
public int Age { get; set;}
}
我将从 Person 创建一个新对象 Class:
dynamic p = new ExpandoObject();
现在这个对象真的是 class Person 的对象吗?它不再与 Person class 相关了??
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);
An unhandled exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll
您不能像这样从动态类型转换为实体类型,因为当时该类型与动态类型没有任何关系,只是看起来像它,因为它具有相似的属性。
但是,您可以序列化动态实例,然后将其反序列化为您拥有的实体类型。我不确定你为什么要这样做...
我认为你在这里混淆了转换和转换的问题。
转换:改变指向的引用类型的行为 一个东西。向上或向下移动对象层次结构或移动到 实现接口
Converting: 从原始源对象创建新对象 不同的类型并通过对该类型的引用访问它。
通常很难知道 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>
声明并在这里解释。