扩展方法是C# 3.0(老赵对VB不熟)中最简单,也是最常用的语言特性之一。这是老赵自以为的一个简单却不失经典的实例:

[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class AttachDataAttribute : Attribute
{
public AttachDataAttribute(object key, object value)
{
this.Key = key;
this.Value = value;
} public object Key { get; private set; } public object Value { get; private set; }
} public static class AttachDataExtensions
{
public static object GetAttachedData(
this ICustomAttributeProvider provider, object key)
{
var attributes = (AttachDataAttribute[])provider.GetCustomAttributes(
typeof(AttachDataAttribute), false);
return attributes.First(a => a.Key.Equals(key)).Value;
} public static T GetAttachedData<T>(
this ICustomAttributeProvider provider, object key)
{
return (T)provider.GetAttachedData(key);
} public static object GetAttachedData(this Enum value, object key)
{
return value.GetType().GetField(value.ToString()).GetAttachedData(key);
} public static T GetAttachedData<T>(this Enum value, object key)
{
return (T)value.GetAttachedData(key);
}
}

AttachDataAttribute是一个自定义属性,可以在各式成员上进行标记。它允许任何类型的Key和任何类型的Value,而开发人员就可以使用GetAttachedData方法,通过一个Key来获得其对应的Value。这个方法比较简单,但是大量用于老赵的项目中。以下便是一例:

public enum AgeRange
{
[AttachData(AgeRangeAttachData.Text, "18岁及以下")]
LessThan18, [AttachData(AgeRangeAttachData.Text, "19至29岁")]
From19To29, [AttachData(AgeRangeAttachData.Text, "30岁及以上")]
Above29
} public enum AgeRangeAttachData
{
Text
} public static class AgeRangeExtensions
{
public static string GetText(this AgeRange range)
{
return range.GetAttachedData<string>(AgeRangeAttachData.Text);
}
}

枚举的每一项其实相当于一个只读的共有Field,也可以加上自定义属性。我们为AgeRange枚举的每一项加上一个以AgeRangeAttachData为Key的附加值作为该枚举的显示文字,并且针对AgeRange编写一个扩展方法GetText。于是代码中就可以使用以下方式来获取某个枚举值的显示文字了:

AgeRange.From19To29.GetText()

关于上面的使用方式,有几个需要提一下的地方:

  • 虽然可以使用任意类型作Key,但是一般建议使用枚举来作为一个强类型的Key。
  • 一般可以为扩展的内容再增加一个扩展方法来获取“同一组”附加数据,以供各个地方重复调用。
  • GetAttachedData使用反射并且遍历所有的AttachDataAttribute,如果您觉得需要提高性能,那么可以自行添加缓存。
  • 以上使用方法在普通情况下可以接受,但其实它并不是Best Practice。一般来说,文字内容都应该提取至外部资源文件中。

AttachDataExtensions的使用很广泛,以后老赵的文章中也会经常使用这个扩展。特此记录,已备引用。

一个利用扩展方法的实例:AttachDataExtensions的更多相关文章

  1. 给IConfiguration写一个GetAppSetting扩展方法

    给 IConfiguration 写一个 GetAppSetting 扩展方法 Intro 在 .net core 中,微软已经默认使用 appsettings.json 来代替 app.config ...

  2. 利用扩展方法重写JSON序列化和反序列化

    利用.NET 3.5以后的扩展方法重写JSON序列化和反序列化,在代码可读性和可维护性上更加加强了. 首先是不使用扩展方法的写法 定义部分: /// <summary>  /// JSON ...

  3. 给 string 添加一个 GetInputStream 扩展方法

    有时候,我们须要读取一些数据,而无论这数据来源于磁盘上的数据文件,还是来源于网络上的数据.于是.就有了以下的 StringExtensions.cs: using System; using Syst ...

  4. C# 向IQueryable添加一个Include扩展方法

    using System; using System.Data.Objects; using System.Linq; namespace OutOfMemory.Codes { /// <su ...

  5. 添加一个js扩展方法

    String.prototype.repeatify=String.prototype.repeatify || function(times){ var str=''; for(var i=0;i& ...

  6. 【开源】OSharp框架解说系列(3):扩展方法

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  7. [置顶] C#扩展方法 扩你所需

    通过前面的学习,了解到:使用扩展方法,可以向现有类型“添加”方法.本文将使用扩展方法来对系统类型,自定义类型及接口进行方法扩展,一睹扩展方法的风采. 1.使用扩展方法来扩展系统类型 String是c# ...

  8. C# 9.0新特性详解系列之二:扩展方法GetEnumerator支持foreach循环

    1.介绍 我们知道,我们要使一个类型支持foreach循环,就需要这个类型满足下面条件之一: 该类型实例如果实现了下列接口中的其中之一: System.Collections.IEnumerable ...

  9. ASP.Net MVC开发基础学习笔记:二、HtmlHelper与扩展方法

    一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归. ...

随机推荐

  1. X光机的原理及构造

    一.X射线的发现 1895年德国物理学家伦琴(W.C.RÖntgen)在研究阴极射线管中气体放电现象时,用年伦琴荣获物理学第一个诺贝尔奖金.科学总是在不断发展的,经伦琴及各国科学家的反复实践和研究,逐 ...

  2. HTTP based RESTful APIs - asp.net web api

    1.HTTP http://www.w3.org/Protocols/rfc2616/rfc2616.html 2.REST是什么http://www.ics.uci.edu/~fielding/pu ...

  3. Ruiy classicsQuotations

    1,IT界,许多人会称自己为菜鸟,而每只菜鸟都会有鹰的梦想; 2,把做十件事精力用来做一件事情,你事业就经典了;

  4. redhat5安装jdk6、eclipse和tomcat6

    redhat5安装jdk6.eclipse和tomcat6 1.安装jdk6 首先下载jdk(jdk-6u13-linux-i586.bin),对于redhat5,本人强烈建议不要安装jdk7,因为有 ...

  5. MVC模式下My97DatePicker日期控件引用注意事项

    My97DatePicker日期控件之前在用webform模式开发的时候,只要 <script language="javascript" type="text/j ...

  6. UIPageViewController-浅析

    一.UIPageViewController概念   控件为我们提供了一种像翻书效果的一种控件.我们可以通过使用UIPageViewController控件,来完成类似图书一样的翻页控制方式.   二 ...

  7. textarea

    ■ 摘要 项目 说明 形式 <textarea>-</textarea> 支持 H2+ / e2+ / N2+ / Fx1+ / Op6+ / Ch1+ / Sa1+ 标签省略 ...

  8. 标准C++的vector使用

    原文:http://blog.csdn.net/pandy1110/article/details/5963908 C++内置的数组支持容器的机制,但是它不支持容器抽象的语义.要解决此问题我们自己实现 ...

  9. easyui combo自动高度(下拉框空白问题)

    设置.combo-panel {max-height:200px;} 在用到easyui-combobox时,设置panelHeight:'auto'

  10. 反射消除String类对象的不可变特性

    大家都知道,在JAVA中字符串一旦声明就不可改变,如果尝试修改字符串的内容,将会重新实例化一个新的字符串对象,这也是为了安全性和效率. 由于字符串在程序之中被大量使用,所以JAVA引入了一个字符串常量 ...