⭐️ .NET 要在国内真正发展起来,必须得有一些追逐梦想的人在做着不计付出的事情,而我希望自己能贡献一份微薄之力。 ⭐️
Skip to main content

29. 粘土对象

版本说明

以下内容仅限 Furion 2.1.12 + 版本使用。

29.1 关于粘土对象

粘土对象是 Furion 框架自创的一种概念,是一种可以模拟弱语言特性的对象,类似 Javascript 一样操作对象。只需通过 Clay 类初始化即可。

为什么起名为 “粘土” 呢?因为这个对象可以自由的添加属性,移除属性,又可以固化成任何对象,具有可拓展、可塑造的特点。

29.1.1 使用场景

粘土对象常用于需要动态构建对象的地方,如 CMS 系统的 ViewModel,或者运行时创建一个新的对象,或者请求第三方 API 情况。

29.1.2 关于性能

粘土性能实际上并不高效,但是性能也并不低下,只不过略输于强类型调用。什么时候使用可以看以上的【使用场景】。

29.2 Clay 对象

Clay 对象是继承自 DynamicObject 的一个特殊对象,提供了像弱语言一样操作对象的方法及索引。

29.3 如何使用

29.3.1 创建一个对象

// 创建一个空的粘土对象dynamic clay = new Clay();// 从现有的对象创建dynamic clay2 = Clay.Object(new {});// 从 json 字符串创建,可用于第三方 API 对接,非常有用dynamic clay3 = Clay.Parse(@"{""foo"":""json"", ""bar"":100, ""nest"":{ ""foobar"":true } }");

29.3.2 读取/获取属性

dynamic clay = Clay.Object(new{    Foo = "json",    Bar = 100,    Nest = new    {        Foobar = true    }});var r1 = clay.Foo; // "json" - string类型var r2 = clay.Bar; // 100 - double类型var r3 = clay.Nest.Foobar; // true - bool类型var r4 = clay["Nest"]["Foobar"]; // 还可以和 Javascript 一样通过索引器获取

29.3.3 新增属性

dynamic clay = Clay.Object(new{    Foo = "json",    Bar = 100,    Nest = new    {        Foobar = true    }});// 新增clay.Arr = new string[] { "NOR", "XOR" }; // 添加一个数组clay.Obj1 = new City { }; // 新增一个实例对象clay.Obj2 = new { Foo = "abc", Bar = 100 }; // 新增一个匿名类

29.3.4 更新属性值

dynamic clay = Clay.Object(new{    Foo = "json",    Bar = 100,    Nest = new    {        Foobar = true    }});// 更新clay.Foo = "Furion";clay["Nest"].Foobar = false;clay.Nest["Foobar"] = true;

29.3.5 删除属性

dynamic clay = Clay.Object(new{    Foo = "json",    Bar = 100,    Nest = new    {        Foobar = true    },    Arr = new string[] { "NOR", "XOR" }});// 删除操作clay.Delete("Foo"); // 通过 Delete 方法删除clay.Arr.Delete(0); // 支持数组 Delete 索引删除clay("Bar");    // 支持直接通过对象作为方法删除clay.Arr(1);    // 支持数组作为方法删除

29.3.6 判断属性是否存在

dynamic clay = Clay.Object(new{    Foo = "json",    Bar = 100,    Nest = new    {        Foobar = true    },    Arr = new string[] { "NOR", "XOR" }});// 判断属性是否存在var a = clay.IsDefined("Foo"); // truevar b = clay.IsDefined("Foooo"); // falsevar c = clay.Foo(); // truevar d = clay.Foooo(); // false;

29.3.7 遍历对象

dynamic clay = Clay.Object(new{    Foo = "json",    Bar = 100,    Nest = new    {        Foobar = true    },    Arr = new string[] { "NOR", "XOR" }});// 遍历数组foreach (string item in clay.Arr){    Console.WriteLine(item); // NOR, XOR}// 遍历整个对象属性及值,类似 JavaScript 的 for (var p in obj)foreach (KeyValuePair<string, dynamic> item in clay){    Console.WriteLine(item.Key + ":" + item.Value); // Foo:json, Bar: 100, Nest: { "Foobar":true}, Arr:["NOR","XOR"]}

29.3.8 转换成具体对象

dynamic clay = new Clay();clay.Arr = new string[] { "Furion", "Fur" };// 数组转换示例var a1 = clay.Arr.Deserialize<string[]>(); // 通过 Deserialize 方法var a2 = (string[])clay.Arr;    // 强制转换string[] a3 = clay.Arr; // 声明方式// 对象转换示例clay.City = new City { Id = 1, Name = "中山市" };var c1 = clay.City.Deserialize<City>(); // 通过 Deserialize 方法var c2 = (City)clay.City;    // 强制转换City c3 = clay.City; // 声明方式

29.3.9 固化粘土

固化粘土在很多时候和序列化很像,但是如果直接调用 Deserialize<object>Deserialize<dynamic> 无法返回实际类型,所以就有了固化类型的功能,如:

// 返回 objectvar obj = clay.Solidify();// 返回 dynamicvar obj1 = clay.Solidify<dynamic>();// 返回其他任意类型var obj2 = clay.Solidify<City>();

29.3.10 输出 JSON

dynamic clay = Clay.Object(new{    Foo = "json",    Bar = 100,    Nest = new    {        Foobar = true    },    Arr = new string[] { "NOR", "XOR" }});// 输出 JSONvar json = clay.ToString(); // "{\"Foo\":\"json\",\"Bar\":100,\"Nest\":{\"Foobar\":true},\"Arr\":[\"NOR\",\"XOR\"]}"
Clay 序列化成 JSON 键大小写控制

默认情况下,Clay 输出成 JSON 后将保持原样输出,如果需要实现键命名控制,则需要先转换成 Dictionary 然后再配置 AddJsonOptions 服务,如:

public IActionResult OutputClay(){    dynamic clay = Clay.Object(new    {       // ....    });    // 转换成 dictionary    var dic = clay.ToDictionary();    return new JsonResult(dic);}

配置序列化 Dictionary 键命名策略支持:

services.AddControllers()        .AddJsonOptions(options =>         {            options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;    // 配置 Dictionary 类型序列化输出         });

29.3.11 输出 XML 对象

dynamic clay = Clay.Object(new{    Foo = "json",    Bar = 100,    Nest = new    {        Foobar = true    },    Arr = new string[] { "NOR", "XOR" }});// 输出 XElementvar xml = clay.XmlElement;

29.3.12 关键字处理

dynamic clay = new Clay();clay.@int = 1;clay.@event = "事件";

29.3.13 转换成字典类型

dynamic clay = Clay.Object(new { name = "张三" });clay.name = "百小僧";Dictionary<string, object> parms = clay.ToDictionary();

29.4 反馈与建议

与我们交流

给 Furion 提 Issue