zoukankan      html  css  js  c++  java
  • C# 扩展方法

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace CommonSD
    {
        public static class MyExtensions
        {
            public static void DisplayDefiningAssembly(this object obj) // 
            {
                //Console.WriteLine("{0} lives here:=> {1}
    ", obj.GetType().Name, Assembly.GetAssembly(obj.GetType()).GetName().Name);
            }
    
            public static int ReverseDigits(this int i)
            {
                // 把int翻译为string然后获取所有字符
                char[] digits = i.ToString().ToCharArray();
                // 现在反转数组中的项
                Array.Reverse(digits);
                // 放回string
                string newDigits = new string(digits);
                // 最后以int返回修改后的字符串
                return int.Parse(newDigits);
            }
    
            public static int ToInt(this string value)
            {
                return int.Parse(value);
            }
        }
    }

    什么是扩展方法?回答这个问题之前,先看看我们一般情况下方法的调用。类似这样的通用方法你一定写过:

    复制代码
            static void Main(string[] args)
            {
    
                string strRes = "2013-09-08 14:12:10";
                var dRes = GetDateTime(strRes);
            }
    
        
            //将字符串转换为日期
            public static DateTime GetDateTime(string strDate)
            {
                return Convert.ToDateTime(strDate);
            }
    
            //得到非空的字符串
            public static string GetNotNullStr(string strRes)
            {
                if (strRes == null)
                    return string.Empty;
                else
                    return strRes;
            }
    复制代码

    或者在项目中有一个类似Utils的工具类,里面有多个Helper,例如StringHelper、XmlHelper等等,每个Helper里面有多个static的通用方法,然后调用的时候就是StringHelper.GetNotNullStr("aa");这样。还有一种普通的用法就是new 一个对象,通过对象去调用类里面的非static方法。反正博主刚开始做项目的时候就是这样写的。后来随着工作经验的累积,博主看到了扩展方法的写法,立马就感觉自己原来的写法太Low了。进入正题。

    1、.Net内置对象的扩展方法

    .Net内部也有很多定义的扩展方法,例如我们Linq常用的Where(x=>x==true)、Select()等等。当你转到定义的时候你很容易看出来:public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)。当然我们也可以给.Net对象新增扩展方法,比如我们要给string对象加一个扩展方法(注意这个方法不能和调用的Main方法放在同一个类中):

    复制代码
            public static string GetNotNullStr(this string strRes)
            {
                if (strRes == null)
                    return string.Empty;
                else
                    return strRes ;
            }
    复制代码

    然后在Main方法里面调用:

            static void Main(string[] args)
            {
                string strTest = null;
                var strRes = strTest.GetNotNullStr();
            }

    简单介绍:public static string GetNotNullStr(this string strRes)其中this string就表示给string对象添加扩展方法。那么在同一个命名空间下面定义的所有的string类型的变量都可以.GetNotNullStr()这样直接调用。strTest.GetNotNullStr();为什么这样调用不用传参数,是因为strTest就是作为参数传入到方法里面的。你可以试试。使用起来就和.Net framework定义的方法一样:

         当然除了string,你可以给.Net内置的其他对象加扩展方法,例如给DataGridViewRow的扩展方法:

    复制代码
    //DataGridViewRow的扩展方法,将当前选中行转换为对应的对象
            public static T ToObject<T>(this DataGridViewRow item) where T:class
            {
                var model = item.DataBoundItem as T;
                if (model != null)
                    return model;
                var dr = item.DataBoundItem as System.Data.DataRowView;
                model = (T)typeof(T).GetConstructor(new System.Type[] { }).Invoke(new object[] { });//反射得到泛型类的实体
                PropertyInfo[] pro = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);
                Type type = model.GetType();
                foreach (PropertyInfo propertyInfo in pro)
                {
                    if (Convert.IsDBNull(dr[propertyInfo.Name]))
                    {
                        continue;
                    }
                    if (!string.IsNullOrEmpty(Convert.ToString(dr[propertyInfo.Name])))
                    {
                        var propertytype = propertyInfo.PropertyType;
                    }
                }
                return model;
            }
    复制代码
    View Code

    这样看上去就像在扩展.Net Framework。有没有感觉有点高大上~

    2、一般对象的扩展方法

         和Framework内置对象一样,自定义的对象也可以增加扩展方法。直接上示例代码:

        public class Person
        {
            public string Name { set; get; }
            public int Age { set; get; }
        }
    复制代码
            //Person的扩展方法,根据年龄判断是否是成年人
            public static bool GetBIsChild(this Person oPerson)
            {
                if (oPerson.Age >= 18)
                    return false;
                else
                    return true;
            }
    复制代码

    Main方法里面调用:

    var oPerson1 = new Person();
    oPerson1.Age = 20;
    var bIsChild = oPerson1.GetBIsChild();        

    和string扩展方法类似,就不多做解释了。

    3、泛型对象的扩展方法

          除了上面两种之外,博主发现其实可以定义一个泛型的扩展方法。那么,是不是所有的类型都可以直接使用这个扩展方法了呢?为了保持程序的严谨,下面的方法可能没有实际意义,当开发中博主觉得可能存在这种场景:

    复制代码
    public static class DataContractExtensions
    {
      //测试方法
      public static T Test<T>(this T instance) where T : Test2
      {
           T Res = default(T);
           try
           {
               Res.AttrTest = instance.AttrTest.Substring(0,2);
               //其他复杂逻辑...
    
    
          }
          catch
          { }
          return Res;
      }
    
    }
    
    public class Test2
    {
      public string AttrTest { set; get; }
    }
    复制代码

    使用扩展方法有几个值得注意的地方:

    (1)扩展方法不能和调用的方法放到同一个类中

    (2)第一个参数必须要,并且必须是this,这是扩展方法的标识。如果方法里面还要传入其他参数,可以在后面追加参数

    (3)扩展方法所在的类必须是静态类

    (4)最好保证扩展方法和调用方法在同一个命名空间下

  • 相关阅读:
    cmd git常用命令使用
    vue2.0 vue-qr生成二维码
    全局css设置
    input 输入框 json格式展示
    eslint 常用配置及说明
    es6中promise 使用总结
    vue 自定义全局组件
    vue element 表头添加斜线
    indexedDB 使用
    黑客攻防从入门到精通(攻防与脚本编程篇)
  • 原文地址:https://www.cnblogs.com/zhang1f/p/11106081.html
Copyright © 2011-2022 走看看