扩展方法是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. xml中,button改变背景颜色方法

    在画几个设置界面,用到了button控件,对于button空间的背景色在不同状态下的颜色改变方法,做了一下尝试,发现了两种背景颜色改变的方法,就总结了下. 方法一尝试了好多遍才好,要点在于,在sele ...

  2. 浅析jquery中attr属性和prop属性的区别

    最近在做项目的时候,发现到了prop这个属性,然后之前一直使用的是attr属性,觉得感觉上都差不多,jQuery也不可能专门做了两个相同的属性撒.所以就结合这两个属性研究了一下,也谈谈我对他们最简单最 ...

  3. 实现简答LinkedList

    package com.表栈和队列; import java.util.Iterator; /**  * 实现LinkedList  * 60页  * @author zj  *  * @param ...

  4. java 命令行制定logback参数

    -Dlogback.configurationFile=file:///export/Workspace/apache-cassandra/apache-cassandra-main/target/b ...

  5. JAVA Socket连接服务器时可能抛出的异常

    1.UnknownHostException:host(非ip)无法识,就会报该异常,www.google.com.hk这个虽然也ping不通,但是不会报该错,因为他是一个确实存在的域名.他会报Con ...

  6. Javascript 【JSON对象】

    var box = JSON.parse(json);     //将字符串解析为JSON var json = JSON.stringify(box);    //讲JSON转换为字符串 var b ...

  7. zepto.js 处理Touch事件(实例)

    处理Touch事件能让你了解到用户的每一根手指的位置,在touch事件触发的时候产生,可以通过touch event handler的event对象取到,如果基于zepto.js开发,一般是通过eve ...

  8. asp.net文件下载

    protected void btn_Down(object sender, EventArgs e) { string filePath = Server.MapPath("/TradeL ...

  9. windows server 2003进行相邻磁盘扩容(server 2008的直接右键就可以解决)

    vCenter下的win server 2003 的D盘需要扩容,解决办法是,先将D盘由原来的200GB增加到了2TB(win server 2003选择MBR的限制),重启win server 20 ...

  10. *++p和*p++的区别

    *p++:先是用*p这个值,然后再使p的地址加1. #include<iostream>using namespace std;int main(){    char s[81]=&quo ...