怎样动态给object添加属性?

lookjoil3 2018-09-26 09:46:58
比如我程序里有一行:
object obj = new { };
然后我从网络抓取到以下文本内容:
{
"clickRequest": {
"account": "ge4tonrx",
"candyId": 4
}
}
怎样给obj添加属性并赋值,使它成为这个抓取到的文本所描述的结构?
也就是实现为obj添加一个clickRequest属性,并且:
obj.clickRequest=new {account="ge4tonrx", candyId=4};
...全文
1761 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
所以如果从一个基本问题我们能提醒你去看出整个设计理念和思维方式,可能引起有些人”害怕“,他怕在公司里混不下去了,怕后来者学到了更加先进实用的学习理念从而超过自己。唉!
  • 打赏
  • 举报
回复
嗯,不带类型参数的 DeserializeObject 方法实际上会返回一个 JToken,具体到这里的 json 字符串也就是返回 JObject 类型对象。而 JObject 也是一个跟 ExpandoObject 基本上一样意思的字典类型(因为人家 Newtonsoft.Json 出来的时候,微软还没有发明 ExpandoObject 呢!)。 所以这里的关键我还是强调,一个真正懂得抽象的人,同时也懂得那个最清楚的具体类型。往往对于同样是看似很有意义的问题,有一个分水岭:有的人说“我的每一个 .net 开发创意都值10万块钱,让我拍拍脑袋设计一个好想法,得给我相当于10万块钱的酬劳”。然后我们就来看看这样的人具体怎么“落地”就能知道他会不会很容易被别人当作”程序骗子“,只要是他能把具体类型说出来(我们允许重构,但是必须能每一次都说出具体类型)就是编程上有诚信的,如果只是自顶向下地概念分解那么在工作中你就会发现身边的这样的工程师有可能是位善于伪装的南郭先生。
  • 打赏
  • 举报
回复
这个逻辑其实很简单: 所有的对象都是 object,而 c#(以至于 .net 平台)显然并不是什么“动态”的,你只有了解了具体的可以达到动态效果的 Class 和 语法糖,才能实现你要的创意。 这其实是个很有意义的问题,这个问题不仅仅问出了具体的“动态字典”类型,而且问出了软件工程的一些想法怎么在一个强类型、靠谱的语言和平台里边落地的问题。当你使用 c# 进行看i发时,一旦有一个新的想法,你就要求寻找对应的框架。而不是打破 object 的规范去变成“动态object”。
liulilittle 2018-09-30
  • 打赏
  • 举报
回复
dotnet是不允许运行时动态对object添加属性的,但是可以利用csharp.net 4.0的dynamic语法特性来处理。 microsoft在.net4.0中提供了一个很实用的 ExpandoObject class 可以基于dynamic语法动态添加一个属性(看上去的)
慧眼识狗熊 2018-09-30
  • 打赏
  • 举报
回复
ExpandoObject,就这个,挺好用的
lookjoil3 2018-09-29
  • 打赏
  • 举报
回复
引用 1 楼 daixf_csdn 的回复:
object obj = new { };
改为:
jsonString = "网络抓取内容";
JavaScriptSerializer jss = new JavaScriptSerializer();
dynamic obj = jss.DeserializeObject(jsonString);

可以访问:obj.clickRequest.account


谢谢回复啊,不过你回复的这个方法得到的是一个Dictionary`2类型的,并不是添加了属性,而且也不能实现访问obj.clickRequest.account
lookjoil3 2018-09-29
  • 打赏
  • 举报
回复
我前面的帖子之前都结帖了,你看到的结帖率0是页面未刷新。
threenewbee 2018-09-29
  • 打赏
  • 举报
回复
ExpandoObject 本质上它是一个字典,项就是你的属性名,值就是属性值
Logerlink 2018-09-29
  • 打赏
  • 举报
回复
sp123 six six six
  • 打赏
  • 举报
回复
要注意一点,“不要滥用 object 这个字眼儿”。真正懂得抽象的人,一定也懂得具体。绝不是一个仅仅会无限地说 object(就好像拿着一个锤子,见到钉子就要砸一砸)的人。只会说 object 这个词儿而不知道具体实现时最底层最真实的类型是什么(比如说 ExpandoObject)那长此以往就成了编程“骗子”,只会层层分解概念而不会先落地之后再抽象。所以编程设计,既要有创意,又要先落地;既要学会上层建筑,又要全面了解基础。
  • 打赏
  • 举报
回复
ExpandoObject 类型实现了“动态添加特性”的需求,它实际上是字典,可以动态添加字典项。只不过需要使用字典的 .Add(key,value) 的语法形式。 而 dynamic 语法糖则可以替代糟糕的反射语法,处理弱类型(开发时无法提示,编译时没有靠谱的语义检查,但是最初写代码比较随意和简单)。这可以实现你随时使用“点语法”来增加属性的语法格式要求。 你可以嵌入任意深度层次的自定义属性,上面的代码中使用一个 dynamic 声明的变量赋值给 .C 就行了。
  • 打赏
  • 举报
回复
例如
var x = new ExpandoObject();
dynamic y = x;
y.A = 1;
y.B = "1234";
y.C = new List<DateTime> { new DateTime(208, 9, 29) };
y.clickRequest = new ExpandoObject();
y.clickRequest.account = "hello";
y.clickRequest.number = 934234;
你可以随意增加新的“属性”,这里的“基础”是 ExpandoObject 类型概念,而“上层建筑”是 dynamic 语法糖。
xuzuning 2018-09-29
  • 打赏
  • 举报
回复
如果不预先定义类型,就不可能用 obj.clickRequest.account 进行访问
因为编译器做不到未仆先知,obj.clickRequest.account 无法通过编译
  • 打赏
  • 举报
回复
.net 提供了 ExpandoObject 类型可以实现这类 IDictionary<string,object> 结构的管理。例如
var x = new ExpandoObject();
dynamic y = x;
y.A = 1;
y.B = "1234";
y.C = new DateTime(2018, 9, 29);
使用 dynamic 语法糖,使用 ExpandoObject 类型结构为基础,就可以直观地编程管理字典。
圣殿骑士18 2018-09-29
  • 打赏
  • 举报
回复
在已获取的对象上增加值:

string json = "{\"clickRequest\": {\"account\": \"ge4tonrx\",\"candyId\": 4},\"prop1\": 10}";
JavaScriptSerializer jss = new JavaScriptSerializer();
dynamic obj = jss.DeserializeObject(json);
var result = obj["clickRequest"]["account"]; //JavaScriptSerializer反序列化后的访问

dynamic obj2 = JsonConvert.DeserializeObject(json);
var result2 = obj2.clickRequest.account; //JsonConvert反序列化后的访问:Newtonsoft json第三方组件
obj2.firstLevel1 = "abc"; //添加一级新属性和值
obj2.firstLevle2 = new JObject //添加二级属性和值
{
new JProperty("childObjInt", 10),
new JProperty("childObjString", "abc")
};

Console.WriteLine(string.Format("obj/{0}:{1}", obj.GetType().ToString(), result));
Console.WriteLine(string.Format("obj2/{0}: {1}, {2}", obj2.GetType().ToString(), result2, obj2.firstLevle2.childObjInt));
圣殿骑士18 2018-09-29
  • 打赏
  • 举报
回复
引用 5 楼 lookjoil3 的回复:
[quote=引用 1 楼 daixf_csdn 的回复:]


谢谢回复啊,不过你回复的这个方法得到的是一个Dictionary`2类型的,并不是添加了属性,而且也不能实现访问obj.clickRequest.account[/quote]

JavaScriptSerializer转化后,确实是字典,所以访问方式稍微调整一下即可。如果你引入Newtonsoft组件,就可以使用.访问

string json = "{\"clickRequest\": {\"account\": \"ge4tonrx\",\"candyId\": 4},\"prop1\": 10}";
JavaScriptSerializer jss = new JavaScriptSerializer();
dynamic obj = jss.DeserializeObject(json);
var result = obj["clickRequest"]["account"]; //JavaScriptSerializer反序列化后的访问

dynamic obj2 = JsonConvert.DeserializeObject(json);
var result2 = obj2.clickRequest.account; //JsonConvert反序列化后的访问:Newtonsoft json第三方组件

Console.WriteLine(string.Format("obj/{0}:{1}", obj.GetType().ToString(), result));
Console.WriteLine(string.Format("obj2/{0}: {1}", obj2.GetType().ToString(), result2));
圣殿骑士18 2018-09-26
  • 打赏
  • 举报
回复
及时结贴,是发帖人的基本素养,也是做人的基本素养,要认识到这个问题。
别人提供的帮助,如果在你看来一钱不值,只做伸手党,这种心态延伸到生活中,职业中,对自己是百害无一利。
圣殿骑士18 2018-09-26
  • 打赏
  • 举报
回复
object obj = new { };
改为:
jsonString = "网络抓取内容";
JavaScriptSerializer jss = new JavaScriptSerializer();
dynamic obj = jss.DeserializeObject(jsonString);

可以访问:obj.clickRequest.account
圣殿骑士18 2018-09-26
  • 打赏
  • 举报
回复
另外,你结帖率0也太夸张了,这样以后没人想回答你的问题。

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧