扩展方法 之 基本数据篇

  前一篇我列举了几个最常用到的基于Asp.Net的扩展方法,而这一篇基于基本数据的扩展方法理应不会逊一筹,因为它不局限于Asp.Net。何谓基本数据,这里直接摆定义:

  C# 中有两种基本数据类型:值类型和引用类型。 值类型包括:简单类型、结构类型、枚举类型;引用类型包括:Object 类型、类类型、接口、代表元、字符串类型、数组。

  说白了这篇就是扩展 int, string, double, DateTime...等基本类型。这么多数据类型,如果int来个扩展,double也来个扩展,肯定会是一个造金字塔工程。幸好有泛型帮我们,但是有时泛型也不是万能的,这个以后有机会再说。

  为什么我们需要扩展方法?一句话:提高写代码的速度,语义也清晰。按道理说,基于基本数据的扩展方法应该经常被用到才有意义,否则只会“污染”被扩展的元素。而怎么才算常用,这可没什么标准,也不是我一个人说了算。所以,以下的扩展方法大家就根据自己的经验判断是否常用吧,至少我的项目是用了不少。

1. In 判断一个元素是否在一个集合
里面

(这是我目前为止见到最好的扩展方法之一)

1.1 ScottGu 最初的版本:

1.2 后经 鹤冲天 的润色:c#扩展方法奇思妙用高级篇一:改进 Scottgu 的 "In" 扩展

//ScottGu In扩展 改进

public static bool In(this T t, params T[] c)

{

return c.Any(i => i.Equals(t));

}

1.3 最后我也来凑个热闹:

public static bool In(this T t, params T[] c)

{

return c.Contains(t);

//return c.Any(i => i.Equals(t));

}

示例:

bool exist1= 2.In(1, 2, 3);

string[] helloworld = { "Hello", "World", "!" };

bool exist2 = "Hello".In(helloworld );2. InRange 判断一个元素是否在某个范围public static bool InRange(this IComparable t, T minT, T maxT)

{

return t.CompareTo(minT) >= 0 && t.CompareTo(maxT) <= 0;

}

public static bool InRange(this IComparable t, object minT, object maxT)

{

return t.CompareTo(minT) >= 0 && t.CompareTo(maxT) <= 0;

}

示例:

//判断3是否在2~3的范围

bool result1 = 3.InRange(2, 3);

//判断3.14是否在3.13~3.15的范围

bool result2 = 3.14.InRange(3.13, 3.15);

//判断今天是否在2000年1月1日~2010年1月1日的范围

bool result3 = DateTime.Now.InRange(new DateTime(2000, 1, 1), new DateTime(2010, 1, 1));

//判断牛B是否在牛A和牛C之间

bool result4 = "牛B".InRange("牛A", "牛C");

上面最后一个示例来源于这句网语:做一个徘徊于牛A和牛C之间的人

3. 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 = 0;

foreach (T element in source)

action(element, i++);

}

注:这两个并非原创,但实在太通用,已经找不到出处。

示例1:Linq to SQL 批量更新

//Linq to SQL

IQueryable query = ...;

query.ForEach(c => c.Name = "Bruce");

db.SubmitChanges();

示例2:设置行号

List list = ...;

list.ForEach((c,i) => c.Line = (i+1));
4. 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(StreamingContextStates.Clone));

binaryFormatter.Serialize(memStream, obj);

memStream.Seek(0, SeekOrigin.Begin);

return binaryFormatter.Deserialize(memStream);

}

}

示例1:克隆单个实体

Entity entity = new Entity { Name = "Bruce", Line = 1 };

Entity cloneEntity = entity.Clone();

bool same = entity.Equals(cloneEntity);

// 被克隆的类必须标记为可序列化

[Serializable]

class Entity

{

public string Name { get; set; }

public int Line { get; set; }

}

最后entity.Equals(cloneEntity);的结果是false,表明已经成功克隆了一个新对象。

示例2:克隆集合

List list = new List();

list.Add(new Entity { Name = "Bruce", Line = 1 });

list.Add(new Entity { Name = "Jack", Line = 2 });

list.Add(new Entity { Name = "Rose", Line = 3 });

list.Add(new Entity { Name = "Tony", Line = 4 });

List cloneList = list.Clone();

总结:

扩展方法为我们封装了常用的逻辑,与以往静态方法不同的是,从使用者的角度来看已经不用关心这个方法是来自于那个类,主要记着命名空间就可以。所以,一般做法是,所有扩展方法属于同一命名空间,并按被扩展的类型分类,如下图:

最后要说的是,其实string类型的扩展方法应该是使用频率最高的,但基于string的扩展方法网上随便一抓一大把,这里就不重复列举了。

时间: 2024-11-03 21:10:50

扩展方法 之 基本数据篇的相关文章

艾伟_转载:扩展方法 之 基本数据篇

前一篇我列举了几个最常用到的基于Asp.Net的扩展方法,而这一篇基于基本数据的扩展方法理应不会逊一筹,因为它不局限于Asp.Net.何谓基本数据,这里直接摆定义: C# 中有两种基本数据类型:值类型和引用类型. 值类型包括:简单类型.结构类型.枚举类型:引用类型包括:Object 类型.类类型.接口.代表元.字符串类型.数组. 说白了这篇就是扩展 int, string, double, DateTime...等基本类型.这么多数据类型,如果int来个扩展,double也来个扩展,肯定会是一个

艾伟_转载:扩展方法 之 Redirect 篇

前言: 单看标题,可能很多朋友不知道我到底想写什么.在写这篇文章前,我自己跟自己斗争了很久,到底该不该写这篇文章?毕竟从现实主义来看,这篇文章可能落入"瞎扯淡"的行列,因为对大多数朋友来说,以下的所有扩展方法可能都不会用到. 如果真是这样,就当作一个"漫无边际"的想法来看好了.如果你根本不想浪费你的宝贵时间,就点这里 Redirect 回博客园主页,呵呵 一个 Redirect 为什么也可以耗费一篇文章的笔墨? 就 Redirect 一词成文的先例估计不会是我,但如

扩展方法 之 Redirect 篇

前言: 单看标题,可能很多朋友不知道我到底想写什么.在写这篇文章前,我自己跟自己斗争了很久,到底该不该写这篇文章?毕竟从现实主义来看,这篇文章可能落入"瞎扯淡"的行列,因为对大多数朋友来说,以下的所有扩展方法可能都不会用到. 如果真是这样,就当作一个"漫无边际"的想法来看好了.如果你根本不想浪费你的宝贵时间,就点这里 Redirect 回博客园主页,呵呵 一个 Redirect 为什么也可以耗费一篇文章的笔墨? 就 Redirect 一词成文的先例估计不会是我,但如

c#扩展方法奇思妙用高级篇八:Type类扩展

Type 类提供了大量的属性和方法,但在一些基础性开发工作中,Type类功能还有些欠缺,尤其上在处理泛型类型时,如可空类型和泛型集合类型.下面的类就针对这些地方进行扩展. 1 public static class TypeHelper 2 { 3 public static bool IsNullableType(this Type type) 4 { 5 return (((type != null) && type.IsGenericType) && 6 (type.

c#扩展方法奇思妙用高级篇七:“树”通用遍历器

先看一个简单的类People(将作为测试用的例子): 1 public abstract class People 2 { 3 public bool IsMale { get; private set; } 4 public abstract IEnumerable<People> Children { get; } 5 } People类有一个Children属性,返回该People的所有孩子.People类通过Children属性最终可形成一个People树. "树"

c#扩展方法奇思妙用高级篇五:ToString(string format) 扩展

在.Net中,System.Object.ToString()是用得最多的方法之一,ToString()方法在Object类中被定义为virtual,Object类给了它一个默认实现: 1 public virtual string ToString() 2 { 3 return this.GetType().ToString(); 4 } .Net中原生的class或struct,如int,DateTime等都对它进行重写(override),以让它返回更有价值的值,而不是类型的名称.合理重写

c#扩展方法奇思妙用高级篇四:对扩展进行分组管理

从系列文章开篇到现在,已经实现的很多扩展了,但过多的扩展会给我们带来很多麻烦,试看下图: 面对这么多"泛滥"的扩展,很多人都会感到很别扭,的确有种"喧宾夺主"的感觉,想从中找出真正想用的方法来太难了!尽管经过扩展后的string类很"强大",但易用性确很差. 很多人因此感觉扩展应适可而止,不该再继续下去...其实这是一种逃避问题的态度,出现问题我们应该主动去解决,而不是去回避! 有很多种方法可以解决以上问题,最简单的就是使用将扩展放入不同name

c#扩展方法奇思妙用高级篇二:Aggregate扩展其改进

Enumerable.Aggregate 扩展方法在System.Linq命名空间中,是Enumerable类的第一个方法(按字母顺序排名),但确是Enumerable里面相对复杂的方法. MSDN对它的说明是:对序列应用累加器函数.备注中还有一些说明,大意是这个方法比较复杂,一般情况下用Sum.Max.Min.Average就可以了. 看看下面的代码,有了Sum,谁还会用Aggregate呢! public static void Test1() { int[] nums = new int[

c#扩展方法奇思妙用高级篇一:改进Scottgu的"In"扩展

先看下ScottGu对In的扩展: 调用示例1: 调用示例2: 原文地址:New "Orcas" Language Feature: Extension Methods(http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx) 很多介绍扩展方法的也大都使用"In"作为例子,但很少有人再深入想一步.个人感觉这个In扩展的不够彻