C#中类似JavaScript的动态属性

Гро*_*ный 2 c# serialization asp.net-web-api

基本上我用C#等效于以下JavaScript语法:

var obj = {id: 1};
obj["prop1"] = 100;
obj["prop2"] = 200;
Run Code Online (Sandbox Code Playgroud)

是否可以动态地向C#对象添加属性并使用WebAPI控制器操作序列化为JSON?

我的C#对象:

public class MyObject
{
    public int Id { get; set; }
    public MyChildObject[] Chidren { get; set; }

    public int this[string prop]
    {
        get { return Chidren.Single(x => x.PropertyName == prop).Value; }
    }
}

public class MyChildObject
{
    public string PropertyName { get; set; }
    public int Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我想回到客户端的是:

{
    id: 1,
    prop1: 100,
    prop2: 200
}
Run Code Online (Sandbox Code Playgroud)

此测试通过,但显然只是因为在运行时访问属性.但是,它们不是序列化的:

[TestMethod]
public void CanAccessDymaicProperties()
{
    var dto = new MyObject
    {
        Id = 1,
        Chidren = new[]
        {
            new MyChildObject { PropertyName = "prop1",  Value = 100 },
            new MyChildObject { PropertyName = "prop2",  Value = 200 },

        }
    };

    Assert.AreEqual(dto["prop1"], 100);
    Assert.AreEqual(dto["prop2"], 200);
}
Run Code Online (Sandbox Code Playgroud)

mez*_*tou 6

您可以使用ExpandoObjectdynamic关键字:

dynamic o = new ExpandoObject();
o.Prop1 = 100;
o.Prop2 = "Sample";
JsonConvert.SerializeObject(o); // {"Prop1":100,"Prop2":"Sample"}
Run Code Online (Sandbox Code Playgroud)

如果您只需要序列化键/值对的自定义集合,则应使用Dictionary<string, object>:

var dic = new Dictionary<string, object>();
dic["Prop1"] = 100;
dic["Prop2"] = "Sample";
JsonConvert.SerializeObject(dic); // {"Prop1":100,"Prop2":"Sample"}
Run Code Online (Sandbox Code Playgroud)

正如@derloopkat在评论中所说,您也可以使用匿名对象:

var o = new { Prop1 = 100, Prop2 = "Sample" };
JsonConvert.SerializeObject(o);
Run Code Online (Sandbox Code Playgroud)