实用技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > ASP.NET > 实用技巧 > .NET扩展方法

.NET扩展方法使用实例详解

作者:Darren Ji

本文详细讲解了.NET的扩展方法的使用,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

扩展方法有几个必要前提:

扩展基本数据类型

针对DateTime类型写一个扩展方法。

    public static class CalculateAge
    {
        public static int Age(this DateTime date, DateTime birthDate)
        {
            int birthYear = birthDate.Year;
            int currentYear = DateTime.Now.Year;
            if (birthYear >= currentYear)
            {
                throw new Exception("请输入正确的出生日期~~");
            }
            else
            {
                return currentYear - birthYear - 1;
            }
        }
    }

客户端调用。

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("请输入您的出生年份");
                DateTime d = Convert.ToDateTime(Console.ReadLine());
                DateTime dateInstance = new DateTime();
                int age = dateInstance.Age(d);
                Console.WriteLine("您当前的年龄是:{0}", age);
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

扩展接口

有这样的一个产品模型。

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

接口提供获取产品集合的方法。

    public interface IProductService
    {
        IEnumerable<Product> GetProducts();
    }

接口有2个实现类。

    public class FoodProducts : IProductService
    {
        public IEnumerable<Product> GetProducts()
        {
            return new List<Product>
            {
                new Product(){Id = 1, Name = "饼干"},
                new Product(){Id = 2, Name = "牛奶"}
            };
        }
    }

    public class ElectronicProducts : IProductService
    {
        public IEnumerable<Product> GetProducts()
        {
            return new List<Product>
            {
                new Product(){Id = 3, Name = "电风扇"},
                new Product(){Id = 4, Name = "空调"}
            };
        }
    }

针对接口扩展方法。

    public static class ProductServiceExtension
    {
        public static IEnumerable<Product> GetProductsById(this IProductService productService, int id)
        {
            return productService.GetProducts().Where(p => p.Id == id);
        }
    }

客户端调用。

    class Program
    {
        static void Main(string[] args)
        {
            IProductService productService = new FoodProducts();
            Console.WriteLine("食物类别下总数量是;{0}", productService.GetProducts().Count());
            try
            {
                Console.WriteLine("找到的产品名称是:{0}", (productService.GetProductsById(1).SingleOrDefault()).Name);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadKey();
        }
    }

扩展包含私有字段的类 使用反射获取类的私有字段

扩展一个类的时候,有时候会用到该类的私有字段,我们可以通过反射拿到类的私有字段。

有这样的一个类,包含私有字段和公共方法。

    {
        private DateTime _currentTime;

        public void SetTime()
        {
            _currentTime = DateTime.Now;
        }

        public string GetMsg()
        {
            if (_currentTime.Hour < 12)
            {
                return "上午好~~";
            }
            else
            {
                return "下午好~~";
            }
        }
    }

我们希望扩展出一个显示英文信息的问候。

    public static class DisplayMessageExtensions
    {
        public static string GetLocalMsg(this DisplayMessage message, string country)
        {
            //通过反射拿到私有字段
            var privateField = typeof (DisplayMessage).GetField("_currentTime",
                BindingFlags.Instance | BindingFlags.NonPublic);

            //获取该私有字段的值
            var currentDateTime = (DateTime)privateField.GetValue(message);
            if (country == "USA" && currentDateTime.Hour < 12)
            {
                return "Good Morning";
            }
            else
            {
                return "Good Evening";
            }
        }
    }

客户端调用。

    class Program
    {
        static void Main(string[] args)
        {
            DisplayMessage displayMessage = new DisplayMessage();
            displayMessage.SetTime();
            Console.WriteLine("来自中国的问候是:{0}", displayMessage.GetMsg());
            Console.WriteLine("美国人怎么问候?");
            Console.WriteLine("来自美国的问候是:{0}", displayMessage.GetLocalMsg("USA"));
            Console.ReadKey();
        }
    }

扩展一个类的私有嵌套类 通过反射

当一个类有嵌套私有类的时候,扩展该类的时候,有时候会用到该类的嵌套私有类,我们可以通过反射扩展私有嵌套类。

有这样的一个ParentClass类,包含一个私有嵌套类ChildClass.

    public class ParentClass
    {
        public string MessageFromParent()
        {
            return "from parent~~";
        }

        private class ChildClass
        {
            public string MessageFromChild()
            {
                return "from child~";
            }
        }
    }

现在要扩展这个私有嵌套类,为其添加一个转换成大写的方法,通过反射来完成。

    public static class NestedClassExtension
    {
        public static string ToUppeerCaseParentMessage(this ParentClass parent)
        {
            return parent.MessageFromParent().ToUpper();
        }

        public static string ToUpperCaseChildMessage(this object o)
        {
            var childUpper = "";

            //通过反射获取父类中的私有嵌套类
            var privateClass = typeof (ParentClass).GetNestedType("ChildClass", BindingFlags.NonPublic);

            if (o.GetType() == privateClass)
            {
                //通过反射获取嵌套私有类的方法
                var callMethod = privateClass.GetMethod("MessageFromChild");
                childUpper = (callMethod.Invoke(o, null) as string).ToUpper();
            }
            return childUpper;
        }
    }

客户端,首先通过反射获取私有嵌套类的type类型,然后运用私有嵌套类的扩展方法。

try
{
    ParentClass p = new ParentClass();

    //通过反射获取父类私有嵌套类
    var privateClass = typeof (ParentClass).GetNestedType("ChildClass", BindingFlags.NonPublic);

    //通过反射创建父类私有嵌套类的实例
    var c = Activator.CreateInstance(privateClass);

    //通过反射获取父类私有嵌套类的方法
    //var callMethod = privateClass.GetMethod("MessageFromChild");
    Console.WriteLine(c.ToUpperCaseChildMessage());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);   
}
Console.ReadKey();

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

您可能感兴趣的文章:
阅读全文