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

简介:   前一篇我列举了几个最常用到的基于Asp.Net的扩展方法,而这一篇基于基本数据的扩展方法理应不会逊一筹,因为它不局限于Asp.Net。何谓基本数据,这里直接摆定义:  C# 中有两种基本数据类型:值类型和引用类型。

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

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

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

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

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

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

1.1 ScottGu 最初的版本:

step2  

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

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();

总结:

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

image

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

目录
相关文章
|
10月前
|
数据挖掘 编译器 C#
【C#本质论 五】方法和参数
【C#本质论 五】方法和参数
48 0
艾伟_转载:闲说继承
继承已经是一个古老的话题了,不过最近又在一些地方看到有人讨论它,加上自己也有一些想法,因此形成了这篇文章。继承好不好?经典的OO理论说:继承是面向对象的三大基石之一。现代的OO理论说:组合优于继承。这两种说法显然是彼此冲突的。
820 0
艾伟:闲说继承
继承已经是一个古老的话题了,不过最近又在一些地方看到有人讨论它,加上自己也有一些想法,因此形成了这篇文章。继承好不好?经典的OO理论说:继承是面向对象的三大基石之一。现代的OO理论说:组合优于继承。这两种说法显然是彼此冲突的。
1015 0
艾伟:表达式树和泛型委托
什么是表达式树?   表达式树又称为表达式目录树,以数据形式表示语言级代码。所有的数据都存储在树结构中,每个结点表示一个表达式(Expression)。要想手动生成表达式树我们需要引用System.Linq.Expressions 命名空间,最重要的一个类是Expression,它是所有表达式的基类。
861 0
艾伟_转载:静态构造函数趣谈!
  类的静态构造函数也叫类型构造器,静态构造器,他调用的时刻由CLR来控制:   CLR会选择如下时间之一来调用静态构造函数:      1,在类型的第一个实例创建之前,或类型的非继承字段或成员第一次访问之前。
709 0
|
C#
艾伟_转载:C#中的委托和事件-抛砖引玉
  最近在学习委托和事件,在书店里面看了好多书,但是都是迷迷的…… 今天在博客园里面看到了 张子阳 所写的博客C#中的委托和事件:http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.
1134 0
|
Windows
艾伟_转载:Silverlight陷阱:注意程序集引用问题
  假定我要用Silverlight类库实现一些通用控件,然后在应用程序中引用这个控件库。当然,控件通常也要访问其他一些第三方或开源的开发包,例如Silverlight Toolkit。   于是这个项目的依赖关系如下: Silverlight Application => Silverlight Control => Silverlight Toolkit。
978 0
|
Java C#
艾伟_转载:虚方法的使用
《编程絮语》之一 C#的语法脱胎于C++,因而保留了virtual关键字,可以定义一个虚方法(或虚属性)。一个类的成员被定义为virtual,就意味着它在告诉自己的子类:我准备了一笔遗产,你可以全盘接受,也可以完全拒绝或者修改我的遗嘱。
816 0
|
.NET
艾伟_转载:把委托说透(2):深入理解委托
在上一篇随笔中我们通过示例逐步引入了委托,并比较了委托和接口。本文将重点剖析委托的实质。 委托在本质上仍然是一个类,我们用delegate关键字声明的所有委托都继承自System.MulticastDelegate。
1079 0
|
SQL C#
艾伟_转载:c#扩展方法奇思妙用变态篇四:string 的翻身革命
   string是各种编程语言中最基础的数据类型,长期以来受尽其它类的压迫,经常被肢解(Substring、Split)、蹂躏(Join)...  而现在string要“翻身闹革命”了,它几乎无所不能,可以为所欲为,令其它类心惊胆颤.
1028 0