• 【读书笔记】 泛型委托


           通过昨天的例子可以看到泛型类型实现IAccount接口的要求过于严厉。为了将Accumulate()方法改为泛型方法,还要去创建一个IAccount接口,然后让Account类继承IAccount接口,然后....杯具( ⊙ o ⊙ )啊! 在今天的例子中,我们可以创建独立于任何接口的泛型方法。这个就需要泛型委托机制来帮忙实现了。

     下面是修改后的泛型委托的例子

    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Linq;
    using System.Text;
    
    namespace GenericMethod
    {
        // 定义一个泛型委托
        // TInput是要累加的对象
        // TSummary是返回类型
        public delegate TSummary Action<TInput, TSummary>(TInput t, TSummary u);
    
        public class Account
        {
            private string name;
            public string Name
            {
                get
                {
                    return name;
                }            
            }
    
            private decimal balance;
            public decimal Balance
            {
                get
                {
                    return balance;
                }
            }
    
            public Account(string name, decimal balance)
            {
                this.name = name;
                this.balance = balance;
            }        
        }
    
        public static class Algorithm
        {
            // 使用委托的泛型方法
            public static TSummary Accumulate<TInput, TSummary>(IEnumerable<TInput> coll, Action<TInput, TSummary> action)
            {
                TSummary sum = default(TSummary);
    
                foreach (TInput input in coll)
                {
                    sum = action(input, sum);
                }
    
                return sum;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                List<Account> accounts = new List<Account>();
                accounts.Add(new Account("Christian", 1500));
                accounts.Add(new Account("Sharon", 2200));
                accounts.Add(new Account("Katie", 1800));
    
                // 通过匿名方法调用
                //decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, delegate(Account a, decimal d){return a.Balance + d;});
                
                // 还可以通过λ表达式调用
                decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, (a, d) => a.Balance + d;);
    
                Console.WriteLine(amount.ToString());
                Console.ReadLine();
    
            }
        }
    }
    
    

    郁闷了,编译有个错误:

    Error 1 ) expected E:\C Sharp\ComputerManager\GenericMethod\GenericMethod\Program.cs 70 102 GenericMethod
    Error 2 Invalid expression term ')' E:\C Sharp\ComputerManager\GenericMethod\GenericMethod\Program.cs 70 103 GenericMethod
    Error 3 Only assignment, call, increment, decrement, and new object expressions can be used as a statement E:\C Sharp\ComputerManager\GenericMethod\GenericMethod\Program.cs 70 102 GenericMethod

    编译怎么出问题了,实在不解,待会儿查下。

    NOTE:偶晕倒,原来是这里出问题了

     decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, (a, d) => a.Balance + d;);

    应该是这样写,多了一个分号囧

     decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, (a, d) => a.Balance + d);

    通过匿名方法调用的那个是没有任何问题的。

    下面的这个就是标准的委托形式了,这个看不懂,就要回去看下委托的章节了。

    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Linq;
    using System.Text;
    
    namespace GenericMethod
    {
        // 定义一个泛型委托
        // TInput是要累加的对象
        // TSummary是返回类型
        public delegate TSummary Action<TInput, TSummary>(TInput t, TSummary u);
    
        public class Account
        {
            private string name;
            public string Name
            {
                get
                {
                    return name;
                }            
            }
    
            private decimal balance;
            public decimal Balance
            {
                get
                {
                    return balance;
                }
            }
    
            public Account(string name, decimal balance)
            {
                this.name = name;
                this.balance = balance;
            }        
        }
    
        public static class Algorithm
        {
            // 使用委托的泛型方法
            public static TSummary Accumulate<TInput, TSummary>(IEnumerable<TInput> coll, Action<TInput, TSummary> action)
            {
                TSummary sum = default(TSummary);
    
                foreach (TInput input in coll)
                {
                    sum = action(input, sum);
                }
    
                return sum;
            }
    
            public static decimal AccountAdder(Account a, decimal d)
            {
                return a.Balance + d;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                List<Account> accounts = new List<Account>();
                accounts.Add(new Account("Christian", 1500));
                accounts.Add(new Account("Sharon", 2200));
                accounts.Add(new Account("Katie", 1800));
    
                // 通过匿名方法调用
                //decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, delegate(Account a, decimal d){return a.Balance + d;});
                
                // 还可以通过λ表达式调用
                //decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, (a, d) => a.Balance + d;);
    
                // 使用标准的委托形式
                // 单独再写一个AccountAdder方法
                decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, Algorithm.AccountAdder);
    
                Console.WriteLine(amount.ToString());
                Console.ReadLine();
    
            }
        }
    }
    
    

    这样就很灵活了,你可以在Action方法里面想做什么就做什么,可以乘法除法都可以了。

    下面再做一个扩展可以在Accumulate的时候加入一个委托应用来检查某个账目是否应累加进去。

    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Linq;
    using System.Text;
    
    namespace GenericMethod
    {
        // 定义一个泛型委托
        // TInput是要累加的对象
        // TSummary是返回类型
        public delegate TSummary Action<TInput, TSummary>(TInput t, TSummary u);
    
        public class Account
        {
            private string name;
            public string Name
            {
                get
                {
                    return name;
                }            
            }
    
            private decimal balance;
            public decimal Balance
            {
                get
                {
                    return balance;
                }
            }
    
            public Account(string name, decimal balance)
            {
                this.name = name;
                this.balance = balance;
            }        
        }
    
        public static class Algorithm
        {
            // 使用委托的泛型方法
            public static TSummary Accumulate<TInput, TSummary>(IEnumerable<TInput> coll, Action<TInput, TSummary> action)
            {
                TSummary sum = default(TSummary);
    
                foreach (TInput input in coll)
                {
                    sum = action(input, sum);
                }
    
                return sum;
            }
    
            public static decimal AccountAdder(Account a, decimal d)
            {
                return a.Balance + d;
            }
    
            public static TSummary AccumulateIf<TInput, TSummary>(IEnumerable<TInput> coll, Action<TInput, TSummary> action, Predicate<TInput> match)
            {
                TSummary sum = default(TSummary);
    
                foreach (TInput a in coll)
                {
                    if (match(a))
                    {
                        sum = action(a, sum);
                    }
                }
                return sum;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                List<Account> accounts = new List<Account>();
                accounts.Add(new Account("Christian", 1500));
                accounts.Add(new Account("Sharon", 2200));
                accounts.Add(new Account("Katie", 1800));
    
                // 通过匿名方法调用
                //decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, delegate(Account a, decimal d){return a.Balance + d;});
                
                // 还可以通过λ表达式调用
                //decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, (a, d) => a.Balance + d);
    
                // 使用标准的委托形式
                // 单独再写一个AccountAdder方法
                // decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, Algorithm.AccountAdder);
    
                // 新委托方法的调用
                decimal amount = Algorithm.AccumulateIf<Account, decimal>(accounts, (a, d) => a.Balance + d, a => a.Balance > 2000);
    
                Console.WriteLine(amount.ToString());
                Console.ReadLine();
            }
        }
    }
    
    

     对Array类使用泛型方法

    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Linq;
    using System.Text;
    
    namespace ArrayGenericDelegate
    {
        public class Person
        {
            private string firstName;
            public string FirstName
            {
                get
                {
                    return firstName;
                }            
            }
    
            private string lastName;
            public string LastName
            {
                get
                {
                    return lastName;
                }
            }
    
            public Person(string firstname, string lastname)
            {
                this.firstName = firstname;
                this.lastName = lastname;
            }
        }
    
        public class Racer
        {
            public string Name
            {
                get;
                set;
            }
    
            public string Team
            {
                get;
                set;
            }
    
            public Racer(string name)
            {
                this.Name = name;
            }
        }
    
    
        class Program
        {
            static void Main(string[] args)
            {
                Person[] persons = {
                new Person("Emerson", "Fittipaldi"),
                new Person("Niki", "Lauda"),
                new Person("Ayrton", "Senda"),
                new Person("Michael", "Schumacher")
                };
    
                // 调用Array的Sort泛型方法给Person数组进行首姓名排序
                Array.Sort(persons, (p1, p2) => p1.FirstName.CompareTo(p2.FirstName));
    
                // 调用Array的Foreach泛型方法将Person数组的首姓名输出到控制台
                Array.ForEach(persons, p => Console.WriteLine("{0}", p.FirstName));
                // 调用Array的Foreach泛型方法将Person数组的末姓名输出到控制台
                Array.ForEach(persons, p => Console.WriteLine("{0}", p.LastName));
    
                // 调用Array的FindAll泛型方法查找首字母以S开头的Person类集合
                Person[] sPersons = Array.FindAll(persons, p => p.LastName.StartsWith("S"));
    
                // 调用Array的ConvetAll泛型方法将一种类型数组转换为另一种类型数组
                Racer[] racers = Array.ConvertAll<Person, Racer>(persons, p => new Racer(String.Format("{0} {1}", p.FirstName, p.LastName)));
    
                Console.ReadLine();
            }
        }
    }
    
    

    从上面的例子看出Array类的泛型方法还是很强大的。

    伪python爱好者,正宗测试实践者。
  • 相关阅读:
    简明Vim练级攻略
    linux之cat命令
    linux之cat,more,less,head,tail
    linux之touch命令修改文件的时间戳
    linux 之创建文件命令
    python开发_function annotations
    python开发_python中的range()函数
    python开发_python中的module
    python开发_python中的函数定义
    python开发_python关键字
  • 原文地址:https://www.cnblogs.com/herbert/p/1745130.html
Copyright © 2020-2023  润新知