C# 中有两种基本数据类型值类型和引用类型 值类型包括简单类型结构类型枚举类型引用类型包括Object 类型类类型接口代表元字符串类型数组
说白了这篇就是扩展 int string double DateTime等基本类型这么多数据类型如果int来个扩展double也来个扩展肯定会是一个造金字塔工程幸好有泛型帮我们但是有时泛型也不是万能的这个以后有机会再说
为什么我们需要扩展方法?一句话提高写代码的速度语义也清晰按道理说基于基本数据的扩展方法应该经常被用到才有意义否则只会污染被扩展的元素而怎么才算常用这可没什么标准也不是我一个人说了算所以以下的扩展方法大家就根据自己的经验判断是否常用吧至少我的项目是用了不少
In 判断一个元素是否在一个集合里面
(这是我目前为止见到最好的扩展方法之一)
ScottGu 最初的版本
后经 鹤沖天 的润色c#扩展方法奇思妙用高级篇一
改进 Scottgu 的 In 扩展
//ScottGu In扩展 改进 public static bool In(this T t params T[] c) { return cAny(i => iEquals(t)); }
最后我也来凑个热闹
public static bool In(this T t params T[] c) { return cContains(t); //return cAny(i => iEquals(t)); }
示例
bool exist= In( );string[] helloworld = { Hello World ! };bool exist = HelloIn(helloworld ); InRange 判断一个元素是否在某个范围
public static bool InRange(this IComparable t T minT T maxT) { return tCompareTo(minT) >= && tCompareTo(maxT) <= ; } public static bool InRange(this IComparable t object minT object maxT) { return tCompareTo(minT) >= && tCompareTo(maxT) <= ; }
示例
//判断是否在~的范围bool result = InRange( ); //判断是否在~的范围bool result = InRange( );//判断今天是否在年月日~年月日的范围bool result = DateTimeNowInRange(new DateTime( ) new DateTime( ));//判断牛B是否在牛A和牛C之间bool result = 牛BInRange(牛A 牛C);
上面最后一个示例来源于这句网语做一个徘徊于牛A和牛C之间的人
ForEach 遍历集合
public static void ForEach(this IEnumerable source Action action){ foreach (T element in source) action(element);} public static void ForEach(this IEnumerable source Actionint> action){ int i = ; foreach (T element in source) action(element i++); }
注这两个并非原创但实在太通用已经找不到出处
示例Linq to SQL 批量更新
//Linq to SQL IQueryable query = ;queryForEach(c => cName = Bruce);dbSubmitChanges();
示例设置行号
List list = listForEach((ci) => cLine = (i+));
Clone 克隆一个对象
public static T Clone(this T t) { return (T)CloneObject(t);} private static object CloneObject(object obj) { using (MemoryStream memStream = new MemoryStream()) { BinaryFormatter binaryFormatter = new BinaryFormatter(null new StreamingContext(StreamingContextStatesClone)); binaryFormatterSerialize(memStream obj); memStreamSeek( SeekOriginBegin); return binaryFormatterDeserialize(memStream); } }
示例克隆单个实体
Entity entity = new Entity { Name = Bruce Line = }; Entity cloneEntity = entityClone(); bool same = entityEquals(cloneEntity); // 被克隆的类必须标记为可序列化 [Serializable] class Entity { public string Name { get; set; } public int Line { get; set; } }
最后entityEquals(cloneEntity);的结果是false表明已经成功克隆了一个新对象
示例克隆集合
List list = new List(); listAdd(new Entity { Name = Bruce Line = }); listAdd(new Entity { Name = Jack Line = }); listAdd(new Entity { Name = Rose Line = }); listAdd(new Entity { Name = Tony Line = }); List cloneList = listClone();总结
扩展方法为我们封装了常用的逻辑与以往静态方法不同的是从使用者的角度来看已经不用关心这个方法是来自于那个类主要记着命名空间就可以所以一般做法是所有扩展方法属于同一命名空间并按被扩展的类型分类如下图
最后要说的是其实string类型的扩展方法应该是使用频率最高的但基于string的扩展方法网上随便一抓一大把这里就不重复列举了