任意 JSON 转成 C# 动态类,无需事先声明一个C#类型,实现json字符串转成dynamic 类
示例:
[csharp] view plaincopyprint?
class Program
{
static void Main(string[] args)
{
string json = "{name:'hooyes',pwd:'hooyespwd',books:{a:'红楼梦',b:'水浒传',c:{arr:['宝玉','林黛玉']}},arr:['good','very good']}";
dynamic dy = ConvertJson(json);
Console.WriteLine(dy.name);
Console.WriteLine(dy.books.a);
Console.WriteLine(dy.arr[1]);
foreach (var s in dy.books.c.arr)
{
Console.WriteLine(s);
}
Console.Read();
}
static dynamic ConvertJson(string json)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() });
dynamic dy = jss.Deserialize(json, typeof(object)) as dynamic;
return dy;
}
}
用到两个自定义的类:DynamicJsonConverter,DynamicJsonObject
[csharp] view plaincopyprint?
public class DynamicJsonConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
if (type == typeof(object))
{
return new DynamicJsonObject(dictionary);
}
return null;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
public override IEnumerable<Type> SupportedTypes
{
get { return new ReadOnlyCollection<Type>(new List<Type>(new Type[] { typeof(object) })); }
}
}
[csharp] view plaincopyprint?
public class DynamicJsonObject : DynamicObject
{
private IDictionary<string, object> Dictionary { get; set; }
public DynamicJsonObject(IDictionary<string, object> dictionary)
{
this.Dictionary = dictionary;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this.Dictionary[binder.Name];
if (result is IDictionary<string, object>)
{
result = new DynamicJsonObject(result as IDictionary<string, object>);
}
else if (result is ArrayList && (result as ArrayList) is IDictionary<string, object>)
{
result = new List<DynamicJsonObject>((result as ArrayList).ToArray().Select(x => new DynamicJsonObject(x as IDictionary<string, object>)));
}
else if (result is ArrayList)
{
result = new List<object>((result as ArrayList).ToArray());
}
return this.Dictionary.ContainsKey(binder.Name);
}
}
string json = "{name:'hooyes',pwd:'hooyespwd',books:{a:'红楼梦',b:'水浒传',c:{arr:['宝玉','林黛玉']}},arr:['good','very good']}";
private void button1_Click(object sender, EventArgs e)
{
dynamic dy = Helpers.ConvertJson(json);
dynamic obj = new DynamicTest();
//动态表达式 在运行时动态解析.译期间不进行任何的类型检查
this.textBox1.Text = obj.Welcome(dy.books.b);
this.textBox1.Text += obj.Welcome(dy.books.c.arr[0]);
//编译期会自动匹配var 变量的实际类型
var varobj = new DynamicTest();
this.textBox1.Text += varobj.Welcome("var");
}
class DynamicTest
{
public string Welcome(string name)
{
return string.Format("Hello {0},welcome to dynamic world.", name);
}
}
运行效果,动态变量确实有方便的地方在:可以在项目再试一下
这里再顺便说一下 c# 的动态类型使用:
应用
1、自动反射
2、COM组件互操作
3、混合编程,例如IronRuby和IronPython
4、处理Html DOM对象
5、还有一种应用,数据传输中格式转换,如:对象转json等,很方便
首先定义两个简单类: public class Class1
{
public string GetData()
{
return "I am class1";
}
public string SayJob()
{
return " 职业: 我是一名软件工程师!";
}
}
public class Class2
{
public string GetData()
{
return "I am class2";
}
public string SayBirthday()
{
return " 出生日期:"+ DateTime.Now.AddYears(-22).ToString();
}
}
namespace dynamic使用
{
/// <summary>
/// 这里演示 使用动态变量
/// 1 动态转化 json 为 实体类型 无需事前建模
/// 2 动态调用 不同类的方法
/// 根据传入的类型来决定调用哪一个方法
/// </summary>
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string json = "{name:'hooyes',pwd:'hooyespwd',books:{a:'红楼梦',b:'水浒传',c:{arr:['宝玉','林黛玉']}},arr:['good','very good']}";
private void button1_Click(object sender, EventArgs e)
{
dynamic dy = Helpers.ConvertJson(json);
dynamic obj = new DynamicTest();
//动态表达式 在运行时动态解析.译期间不进行任何的类型检查
this.textBox1.Text = obj.Welcome(dy.books.a) + "\r\n";
this.textBox1.Text += obj.Welcome(dy.books.c.arr[0]) + "\r\n";
this.textBox1.Text += obj.testDynamicparam(new Class1() as dynamic) + "\r\n";
this.textBox1.Text += obj.testDynamicparam(new Class2() as dynamic) + "\r\n";
//编译期会自动匹配var 变量的实际类型
var varobj = new DynamicTest();
this.textBox1.Text += varobj.Welcome("var");
}
class DynamicTest
{
public string Welcome(string name)
{
return string.Format("Hello {0}", name);
}
public string testDynamicparam(dynamic classdy)
{
string str = "";
if (classdy is Class1)
{
str = classdy.SayJob();
}
else if (classdy is Class2)
{
str = classdy.SayBirthday();
}
return classdy.GetData() + str;
}
}
}
}
界面演示: