C#回顾 - 8.利用反射动态创建对象
2016-12-05 14:36
435 查看
拿微信消息返回的示例数据实验
var data = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId></xml>";
创建一个消息枚举
/// <summary>
/// 消息类型枚举
/// </summary>
public enum MsgType
{
/// <summary>
/// 文本消息
/// </summary>
TEXT,
/// <summary>
/// 图片消息
/// </summary>
IMAGE,
/// <summary>
/// 语音消息
/// </summary>
VOICE,
/// <summary>
/// 视频消息
/// </summary>
VIDEO,
/// <summary>
/// 小视频消息
/// </summary>
SHORTVIDEO,
/// <summary>
/// 地理位置消息
/// </summary>
LOCATION,
/// <summary>
/// 链接消息
/// </summary>
LINK,
/// <summary>
/// 事件类型
/// </summary>
EVENT
}
因为消息类型的大多数属性都相同,创建一个基类
public abstract class BaseMsg
{
/// <summary>
/// 开发者微信号
/// </summary>
public string ToUserName { get; set; }
/// <summary>
/// 发送方帐号(一个OpenID)
/// </summary>
public string FromUserName { get; set; }
/// <summary>
/// 消息创建时间 (整型)
/// </summary>
public string CreateTime { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MsgType MsgType { get; set; }
}
再创建相应缺少类的属性
/// <summary>
/// 文本消息类型(例外)
/// </summary>
public class MsgText : BaseMsg
{
/// <summary>
/// 文本消息内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 消息Id,64位整型
/// </summary>
public string MsgId { get; set; }
}
/// <summary>
/// 图片消息类型(例外)
/// </summary>
public class MsgImage : BaseMsg
{
/// <summary>
/// 图片链接
/// </summary>
public string PicUrl { get; set; }
/// <summary>
/// 消息Id,64位整型
/// </summary>
public string MsgId { get; set; }
/// <summary>
/// 图片消息媒体id,可以调用多媒体文件下载接口拉取数据。
/// </summary>
public string MediaId { get; set; }
}
/// <summary>
/// 语音消息类型(例外)
/// </summary>
public class MsgVoice : BaseMsg
{
/// <summary>
/// 语音消息媒体id,可以调用多媒体文件下载接口拉取数据。
/// </summary>
public string MediaId { get; set; }
/// <summary>
/// 语音格式,如amr,speex等
/// </summary>
public string Format { get; set; }
/// <summary>
/// 消息id,64位整型
/// </summary>
public string MsgID { get; set; }
}
/// <summary>
/// 视频消息类型(例外)
/// </summary>
public class MsgVideo : BaseMsg
{
/// <summary>
/// 视频消息媒体id,可以调用多媒体文件下载接口拉取数据
/// </summary>
public string MediaId { get; set; }
/// <summary>
/// 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
/// </summary>
public string ThumbMediaId { get; set; }
/// <summary>
/// 消息id,64位整型
/// </summary>
public string MsgId { get; set; }
}
/// <summary>
/// 小视频消息类型(例外)
/// </summary>
public class MsgShortVideo : BaseMsg
{
/// <summary>
/// 视频消息媒体id,可以调用多媒体文件下载接口拉取数据
/// </summary>
public string MediaId { get; set; }
/// <summary>
/// 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
/// </summary>
public string ThumbMediaId { get; set; }
/// <summary>
/// 消息id,64位整型
/// </summary>
public string MsgId { get; set; }
}
/// <summary>
/// 地理位置消息类型(例外)
/// </summary>
public class MsgLocation : BaseMsg
{
/// <summary>
/// 地理位置维度
/// </summary>
public string Location_X { get; set; }
/// <summary>
/// 地理位置经度
/// </summary>
public string Location_Y { get; set; }
/// <summary>
/// 地图缩放大小
/// </summary>
public string Scale { get; set; }
/// <summary>
/// 地理位置信息
/// </summary>
public string Label { get; set; }
/// <summary>
/// 消息id,64位整型
/// </summary>
public string MsgId { get; set; }
}
/// <summary>
/// 链接消息类型(例外)
/// </summary>
public class MsgLink : BaseMsg
{
/// <summary>
/// 消息标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 消息描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 消息链接
/// </summary>
public string Url { get; set; }
/// <summary>
/// 消息id,64位整型
/// </summary>
public string MsgId { get; set; }
}
加载消息,转换成对象
public static BaseMsg LoadMsg()
{
var data = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId></xml>";
var doc = XElement.Parse(data);
MsgType msgtype = (MsgType)Enum.Parse(typeof(MsgType), doc.Element("MsgType").Value.ToUpper());
//MsgType msgtype = (MsgType)Enum.Parse(typeof(MsgType), "TEXT");
switch (msgtype)
{
case MsgType.IMAGE:
return ConvertObj<MsgImage>(data);
case MsgType.LINK:
return ConvertObj<MsgLink>(data);
case MsgType.LOCATION:
return ConvertObj<MsgLocation>(data);
case MsgType.VIDEO:
return ConvertObj<MsgVideo>(data);
case MsgType.SHORTVIDEO:
return ConvertObj<MsgShortVideo>(data);
case MsgType.TEXT:
return ConvertObj<MsgText>(data);
case MsgType.EVENT:
return null;
default:
return ConvertObj<BaseMsg>(data);
}
}
利用反射
public static T ConvertObj<T>(string xmlstr)
{
try
{
var xml = XElement.Parse(xmlstr);
var type = typeof(T);
var t = Activator.CreateInstance<T>(); //动态创建实例,相当于 new T()
var tousername = type.GetProperty("ToUserName");//搜索具有指定名称的公共属性
//PropertyInfo.SetValue(object obj, object value, object[] index)
tousername.SetValue(t, Convert.ChangeType(xml.Element("ToUserName").Value, tousername.PropertyType), null);
xml.Element("ToUserName").Remove();
var fromusername = type.GetProperty("FromUserName");
fromusername.SetValue(t,
Convert.ChangeType(xml.Element("FromUserName").Value, fromusername.PropertyType), null);
xml.Element("FromUserName").Remove();
var createtime = type.GetProperty("CreateTime");
createtime.SetValue(t, Convert.ChangeType(xml.Element("CreateTime").Value, createtime.PropertyType), null);
xml.Element("CreateTime").Remove();
var msgType = type.GetProperty("MsgType");
var msgtype = xml.Element("MsgType").Value;
//msgType.SetValue() 是枚举,参数要改变
msgType.SetValue(t, (MsgType)Enum.Parse(typeof(MsgType), msgtype.ToUpper()), null);
xml.Element("MsgType").Remove();
foreach (var element in xml.Elements())
{
var pr = type.GetProperty(element.Name.ToString());
pr.SetValue(t, Convert.ChangeType(element.Value, pr.PropertyType), null);
}
return t;
}
catch (Exception)
{
return default(T);
throw;
}
}
来自为知笔记(Wiz)
var data = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId></xml>";
创建一个消息枚举
/// <summary>
/// 消息类型枚举
/// </summary>
public enum MsgType
{
/// <summary>
/// 文本消息
/// </summary>
TEXT,
/// <summary>
/// 图片消息
/// </summary>
IMAGE,
/// <summary>
/// 语音消息
/// </summary>
VOICE,
/// <summary>
/// 视频消息
/// </summary>
VIDEO,
/// <summary>
/// 小视频消息
/// </summary>
SHORTVIDEO,
/// <summary>
/// 地理位置消息
/// </summary>
LOCATION,
/// <summary>
/// 链接消息
/// </summary>
LINK,
/// <summary>
/// 事件类型
/// </summary>
EVENT
}
因为消息类型的大多数属性都相同,创建一个基类
public abstract class BaseMsg
{
/// <summary>
/// 开发者微信号
/// </summary>
public string ToUserName { get; set; }
/// <summary>
/// 发送方帐号(一个OpenID)
/// </summary>
public string FromUserName { get; set; }
/// <summary>
/// 消息创建时间 (整型)
/// </summary>
public string CreateTime { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MsgType MsgType { get; set; }
}
再创建相应缺少类的属性
/// <summary>
/// 文本消息类型(例外)
/// </summary>
public class MsgText : BaseMsg
{
/// <summary>
/// 文本消息内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 消息Id,64位整型
/// </summary>
public string MsgId { get; set; }
}
/// <summary>
/// 图片消息类型(例外)
/// </summary>
public class MsgImage : BaseMsg
{
/// <summary>
/// 图片链接
/// </summary>
public string PicUrl { get; set; }
/// <summary>
/// 消息Id,64位整型
/// </summary>
public string MsgId { get; set; }
/// <summary>
/// 图片消息媒体id,可以调用多媒体文件下载接口拉取数据。
/// </summary>
public string MediaId { get; set; }
}
/// <summary>
/// 语音消息类型(例外)
/// </summary>
public class MsgVoice : BaseMsg
{
/// <summary>
/// 语音消息媒体id,可以调用多媒体文件下载接口拉取数据。
/// </summary>
public string MediaId { get; set; }
/// <summary>
/// 语音格式,如amr,speex等
/// </summary>
public string Format { get; set; }
/// <summary>
/// 消息id,64位整型
/// </summary>
public string MsgID { get; set; }
}
/// <summary>
/// 视频消息类型(例外)
/// </summary>
public class MsgVideo : BaseMsg
{
/// <summary>
/// 视频消息媒体id,可以调用多媒体文件下载接口拉取数据
/// </summary>
public string MediaId { get; set; }
/// <summary>
/// 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
/// </summary>
public string ThumbMediaId { get; set; }
/// <summary>
/// 消息id,64位整型
/// </summary>
public string MsgId { get; set; }
}
/// <summary>
/// 小视频消息类型(例外)
/// </summary>
public class MsgShortVideo : BaseMsg
{
/// <summary>
/// 视频消息媒体id,可以调用多媒体文件下载接口拉取数据
/// </summary>
public string MediaId { get; set; }
/// <summary>
/// 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
/// </summary>
public string ThumbMediaId { get; set; }
/// <summary>
/// 消息id,64位整型
/// </summary>
public string MsgId { get; set; }
}
/// <summary>
/// 地理位置消息类型(例外)
/// </summary>
public class MsgLocation : BaseMsg
{
/// <summary>
/// 地理位置维度
/// </summary>
public string Location_X { get; set; }
/// <summary>
/// 地理位置经度
/// </summary>
public string Location_Y { get; set; }
/// <summary>
/// 地图缩放大小
/// </summary>
public string Scale { get; set; }
/// <summary>
/// 地理位置信息
/// </summary>
public string Label { get; set; }
/// <summary>
/// 消息id,64位整型
/// </summary>
public string MsgId { get; set; }
}
/// <summary>
/// 链接消息类型(例外)
/// </summary>
public class MsgLink : BaseMsg
{
/// <summary>
/// 消息标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 消息描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 消息链接
/// </summary>
public string Url { get; set; }
/// <summary>
/// 消息id,64位整型
/// </summary>
public string MsgId { get; set; }
}
加载消息,转换成对象
public static BaseMsg LoadMsg()
{
var data = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId></xml>";
var doc = XElement.Parse(data);
MsgType msgtype = (MsgType)Enum.Parse(typeof(MsgType), doc.Element("MsgType").Value.ToUpper());
//MsgType msgtype = (MsgType)Enum.Parse(typeof(MsgType), "TEXT");
switch (msgtype)
{
case MsgType.IMAGE:
return ConvertObj<MsgImage>(data);
case MsgType.LINK:
return ConvertObj<MsgLink>(data);
case MsgType.LOCATION:
return ConvertObj<MsgLocation>(data);
case MsgType.VIDEO:
return ConvertObj<MsgVideo>(data);
case MsgType.SHORTVIDEO:
return ConvertObj<MsgShortVideo>(data);
case MsgType.TEXT:
return ConvertObj<MsgText>(data);
case MsgType.EVENT:
return null;
default:
return ConvertObj<BaseMsg>(data);
}
}
利用反射
public static T ConvertObj<T>(string xmlstr)
{
try
{
var xml = XElement.Parse(xmlstr);
var type = typeof(T);
var t = Activator.CreateInstance<T>(); //动态创建实例,相当于 new T()
var tousername = type.GetProperty("ToUserName");//搜索具有指定名称的公共属性
//PropertyInfo.SetValue(object obj, object value, object[] index)
tousername.SetValue(t, Convert.ChangeType(xml.Element("ToUserName").Value, tousername.PropertyType), null);
xml.Element("ToUserName").Remove();
var fromusername = type.GetProperty("FromUserName");
fromusername.SetValue(t,
Convert.ChangeType(xml.Element("FromUserName").Value, fromusername.PropertyType), null);
xml.Element("FromUserName").Remove();
var createtime = type.GetProperty("CreateTime");
createtime.SetValue(t, Convert.ChangeType(xml.Element("CreateTime").Value, createtime.PropertyType), null);
xml.Element("CreateTime").Remove();
var msgType = type.GetProperty("MsgType");
var msgtype = xml.Element("MsgType").Value;
//msgType.SetValue() 是枚举,参数要改变
msgType.SetValue(t, (MsgType)Enum.Parse(typeof(MsgType), msgtype.ToUpper()), null);
xml.Element("MsgType").Remove();
foreach (var element in xml.Elements())
{
var pr = type.GetProperty(element.Name.ToString());
pr.SetValue(t, Convert.ChangeType(element.Value, pr.PropertyType), null);
}
return t;
}
catch (Exception)
{
return default(T);
throw;
}
}
来自为知笔记(Wiz)
相关文章推荐
- 【转】C# 利用反射动态创建对象
- C# 利用反射动态创建对象
- C#利用反射动态创建对象 带参数的构造函数和String类型 (转载)
- C# 利用反射动态创建对象[摘录]
- C# 利用反射动态创建对象——带参数的构造函数和String类型
- [C#] 利用反射动态创建对象
- C#利用反射动态创建对象 带参数的构造函数和String类型
- C# 利用反射动态创建对象
- C# 利用反射动态创建对象
- C#利用反射动态创建对象 带参数的构造函数和String类型
- C# 利用反射动态创建对象
- C# 利用反射动态创建对象
- C# 利用反射动态创建对象
- C# 利用反射动态创建对象——带参数的构造函数和String类型
- C#利用反射动态创建对象
- C# 利用反射动态创建对象[摘录]
- C# 利用反射动态创建对象[转]
- 利用反射动态创建对象
- 利用反射动态创建对象
- C# 中反射获取某类的子类和根据类型名动态创建对象(转载)