扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。
扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。 仅当你使用 using
指令将命名空间显式导入到源代码中之后,扩展方法才位于范围中。
在编译时绑定扩展方法
可以使用扩展方法来扩展类或接口,但不能重写扩展方法。 与接口或类方法具有相同名称和签名的扩展方法永远不会被调用。 编译时,扩展方法的优先级总是比类型本身中定义的实例方法低。 换句话说,如果某个类型具有一个名为 Process(int i)
的方法,而你有一个具有相同签名的扩展方法,则编译器总是绑定到该实例方法。 当编译器遇到方法调用时,它首先在该类型的实例方法中寻找匹配的方法。 如果未找到任何匹配方法,编译器将搜索为该类型定义的任何扩展方法,并且绑定到它找到的第一个扩展方法。
定义和调用扩展方法
-
定义包含扩展方法的静态类。
-
将扩展方法实现为静态方法,并且使其可见性至少与所在类的可见性相同。
-
此方法的第一个参数指定方法所操作的类型;此参数前面必须加上 this 修饰符。
-
在调用代码中,添加
using
指令,用于指定包含扩展方法类的命名空间。 -
和调用类型的实例方法那样调用这些方法。
对现在有类型进行相关Json对象使用的扩展方法
1.首先项目中需要添加引用Newtonsoft.Json
2.引入命名空间
using Newtonsoft.Json.Converters;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
实现代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Common
{
public static class Json
{
public static object ToJson(this string Json)
{
return Json == null ? null : JsonConvert.DeserializeObject(Json);
}
public static string ToJson(this object obj)
{
var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
return JsonConvert.SerializeObject(obj, timeConverter);
}
public static string ToJson(this object obj, string datetimeformats)
{
var timeConverter = new IsoDateTimeConverter { DateTimeFormat = datetimeformats };
return JsonConvert.SerializeObject(obj, timeConverter);
}
public static T ToObject<T>(this string Json)
{
return Json == null ? default(T) : JsonConvert.DeserializeObject<T>(Json);
}
public static List<T> ToList<T>(this string Json)
{
return Json == null ? null : JsonConvert.DeserializeObject<List<T>>(Json);
}
public static DataTable ToTable(this string Json)
{
return Json == null ? null : JsonConvert.DeserializeObject<DataTable>(Json);
}
public static JObject ToJObject(this string Json)
{
return Json == null ? JObject.Parse("{}") : JObject.Parse(Json.Replace(" ", ""));
}
public static List<T> DataTableToList<T>(DataTable dt) where T : class,new()
{
// 定义集合
List<T> ts = new List<T>();
//定义一个临时变量
string tempName = string.Empty;
//遍历DataTable中所有的数据行
foreach (DataRow dr in dt.Rows)
{
T t = new T();
// 获得此模型的公共属性
PropertyInfo[] propertys = t.GetType().GetProperties();
//遍历该对象的所有属性
foreach (PropertyInfo pi in propertys)
{
tempName = pi.Name;//将属性名称赋值给临时变量
//检查DataTable是否包含此列(列名==对象的属性名)
if (dt.Columns.Contains(tempName))
{
//取值
object value = dr[tempName];
//如果非空,则赋给对象的属性
if (value != DBNull.Value)
{
pi.SetValue(t, value, null);
}
}
}
//对象添加到泛型集合中
ts.Add(t);
}
return ts;
}
public static T GetEntity<T>(DataTable table) where T : new()
{
T entity = new T();
foreach (DataRow row in table.Rows)
{
foreach (var item in entity.GetType().GetProperties())
{
if (row.Table.Columns.Contains(item.Name))
{
if (DBNull.Value != row[item.Name] && row[item.Name] != null)
{
Type type = row[item.Name].GetType();
//判断type类型是否为泛型,因为nullable是泛型类,
if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))//判断convertsionType是否为nullable泛型类
{
//如果type为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(type);
//将type转换为nullable对的基础基元类型
type = nullableConverter.UnderlyingType;
item.SetValue(entity, Convert.ChangeType(row[item.Name], type), null);
}
item.SetValue(entity, Convert.ChangeType(row[item.Name], type), null);
}
}
}
}
return entity;
}
}
}
扩展方法调用代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Data;
using Common; //引入命名空间
namespace Test
{
public class Test1
{
private void GetDataList()
{
DataTable dt = GetDataTable(); //得到数据集
List<DeviceInfo> result = Json.DataTableToList<DeviceInfo>(dt); //调用扩展方法 DataTableToList
var obj = result.ToJson(); //调用扩展方法 ToJson(this object obj)
}
}