我正在尝试使用,System.Dynamic.ExpandoObject
所以我可以在运行时动态创建属性.稍后,我需要传递此对象的实例,并且使用的机制需要序列化.
当然,当我尝试序列化我的动态对象时,我得到了异常:
System.Runtime.Serialization.SerializationException未处理.
在Assembly'System.Core中输入'System.Dynamic.ExpandoObject',Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089'未标记为可序列化.
我可以序列化ExpandoObject吗?是否有另一种方法来创建可序列化的动态对象?也许使用DynamicObject包装器?
我创建了一个非常简单的Windows窗体示例来复制错误:
using System;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Dynamic;
namespace DynamicTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
dynamic dynamicContext = new ExpandoObject();
dynamicContext.Greeting = "Hello";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, dynamicContext);
stream.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud) 有没有办法将属性添加到与字符串值同名的ExpandoObject?
例如,如果我有:
string propName = "ProductNumber";
dynamic obj = new System.Dynamic.ExpandoObject();
Run Code Online (Sandbox Code Playgroud)
我可以创建属性ProductNumber,如:
obj.ProductNumber = 123;
Run Code Online (Sandbox Code Playgroud)
但是,我可以obj.ProductNumber
根据字符串创建属性propName
吗?所以,如果我不知道该属性的名称将是什么,我可以根据此输入创建它.如果使用ExpandoObject无法做到这一点,那么我应该研究C#的其他任何领域?
说我有这个对象:
dynamic foo = new ExpandoObject();
foo.bar = "fizz";
foo.bang = "buzz";
Run Code Online (Sandbox Code Playgroud)
我该如何删除foo.bang
?
我不想简单地将属性的值设置为null - 为了我的目的,我需要完全删除它.此外,我意识到我可以通过从第一个绘制kv对来创建一个全新的ExpandoObject,但这将是非常低效的.
目前在LINQ中,以下编译和工作正常:
var listOfFoo = myData.Select(x => new FooModel{
someProperty = x.prop1,
someOtherProperty = x.prop2
});
public class FooModel{
public string someProperty { get; set; };
public string someOtherProperty { get; set; };
}
Run Code Online (Sandbox Code Playgroud)
但是,过去几个版本的.NET/C#已经扩展了动态对象的作用,例如ExpandoObject
,我想知道是否有办法基本上这样做:
var listOfFoo = myData.Select(x => new ExpandoObject{
someProperty = x.prop1,
someOtherProperty = x.prop2
});
Run Code Online (Sandbox Code Playgroud)
显然,我已经尝试过上面的代码没有成功,但似乎我错过了一些东西.
假设我有一个类,Foo,看起来像这样:
public class Foo : IFoo
{
public Foo()
{
Bars = new List<dynamic>();
}
public IList<dynamic> Bars { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
接口IFoo看起来像:
public interface IFoo
{
IList<dynamic> Bars { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在,当我执行以下操作时:
IFoo foo = new Foo();
dynamic a = new System.Dynamic.ExpandoObject();
a.Prop = 10000;
dynamic b = new System.Dynamic.ExpandoObject();
b.Prop = "Some Text";
foo.Bars.Add(a); // Throws an 'System.Collections.Generic.IList<object>' does not contain a definition for 'Add' - exception!!!!!
foo.Bars.Add(b); // Same here!!!!!
Run Code Online (Sandbox Code Playgroud)
我在这做错了什么?????
我正在使用Rob Conery的Massive ORM,而我无法将结果绑定ExpandoObject
到GridView
.
我确实找到了另一个建议使用名为即兴的框架的Stackoverflow问题,但我不确定这是否适用于此.如果您知道,请提供代码示例以实际转换ExpandoObject
为GridView
控件可以绑定的内容.
最糟糕的情况是,是否有人为Massive实现了一个额外的方法(可以共享)将结果转换ExpandoObject
为POCO?
任何帮助是极大的赞赏.谢谢.
是否有任何方法可以在4.0框架中使用新的动态功能,如ExpandoObject
VB.NET中没有设置Option Strict Off
?使用C#,只有使用您明确声明的变量才会丢失类型安全性dynamic
.但是使用VB,我发现使用这些功能的唯一方法就是Option Strict Off
从一开始就在VB.NET中使用的旧技巧.如果没有Option Strict,文件中的所有内容都会被模糊输入污染,如下所示:
Option Explicit On
Option Strict Off
Option Infer On
Partial Public Class ClassX
Public Sub TestDynamic()
Dim dyn As Object = New System.Dynamic.ExpandoObject()
Dim a As String = 1 ''# Ew!
Dim obj As Object = "999"
dyn.Str = a ''# a is a string, remember? Even though it has a number
''# dyn.Str = 1 : Type = System.String
Console.WriteLine("dyn.Str = …
Run Code Online (Sandbox Code Playgroud) 我注意到具有必需和方法的新ExpandoObject
工具因此应该可以使用集合初始化语法以与向字典添加项目相同的方式向expando对象添加属性.IDictionary<string,object>
IEnumerable<KeyValuePair<string, object>>
Add(string, object)
Dictionary<string,object> dict = new Dictionary<string,object>()
{
{ "Hello", "World" }
};
dynamic obj = new ExpandoObject()
{
{ "foo", "hello" },
{ "bar", 42 },
{ "baz", new object() }
};
int value = obj.bar;
Run Code Online (Sandbox Code Playgroud)
但似乎没有办法做到这一点.错误:
'System.Dynamic.ExpandoObject'不包含'添加'的定义
我认为这不起作用,因为接口是明确实现的.但有没有办法解决这个问题?这工作正常,
IDictionary<string, object> exdict = new ExpandoObject() as IDictionary<string, object>();
exdict.Add("foo", "hello");
exdict.Add("bar", 42);
exdict.Add("baz", new object());
Run Code Online (Sandbox Code Playgroud)
但是集合初始化器语法更整洁.
例如,有一个像下一个的对象:
public class Container
{
public object Data { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
它以这种方式使用:
Container container = new Container
{
Data = new Dictionary<string, object> { { "Text", "Hello world" } }
};
Run Code Online (Sandbox Code Playgroud)
如果我反序列化从序列化上述实例获得的JSON字符串Data
,即使我提供了该属性ExpandoObjectConverter
,它也不会被反序列化为ExpandoObject
:
Container container = JsonConvert.Deserialize<Container>(jsonText, new ExpandoObjectConverter());
Run Code Online (Sandbox Code Playgroud)
如何反序列化使用匿名对象分配的类属性,或者至少不是具体类型ExpandoObject
?
有人回答说我可以使用动态对象.这对我不起作用.我知道我可以这样做,但事实并非如此,因为我需要一个ExpandoObject.谢谢.
其他一些用户回答我可以将JSON字符串反序列化为ExpandoObject
.这不是这个问题的目标.我需要反序列化具有动态属性的具体类型.在JSON字符串中,此属性可以是关联数组.
C#4.0的ExpandoObject是否支持基于Prototype的继承?如果没有,为什么不(它是否按设计?)以及如何实施?如果是,它是如何工作的,与它在Javascript中的工作方式相比有什么不同?