zoukankan      html  css  js  c++  java
  • 一个利用扩展方法的实例:AttachDataExtensions

    扩展方法是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的使用很广泛,以后老赵的文章中也会经常使用这个扩展。特此记录,已备引用。

  • 相关阅读:
    工具.MySQL
    SqlServer.日期时间格式化输出(资料)
    SqlServer2012.安装
    SQL.【转】获取存储过程返回值的几种方式
    SQL.【转】SqlServer如何获取存储过程的返回值
    SQL.@,@@、#,##
    Oracle10g.CentOS6安装_遇到的问题(02)
    jQuery FileUpload 插件[转]
    EF6+Oracle12c+DBFirst+VS2015:EF6.0添加实体模型闪退问题解决
    IIS
  • 原文地址:https://www.cnblogs.com/zhouyunbaosujina/p/3282725.html
Copyright © 2011-2022 走看看