zoukankan      html  css  js  c++  java
  • C#之委托

    委托是C#中非常重要的一个概念,并在C#中得到了丰富的应用,如事件,线程等。那什么是委托呢?具体来说,委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。

    委托具有以下特点:

    • 委托类似于 C++ 函数指针,但它是类型安全的。

    • 委托允许将方法作为参数进行传递。

    • 委托可用于定义回调方法。

    • 委托可以链接在一起;例如,可以对一个事件调用多个方法。

    • 方法不需要与委托签名精确匹配。有关更多信息,请参见协变和逆变。

    • C# 2.0 版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法。

    在C#中使用委托分为三步:

    1.定义委托:

        //声明委托
        public delegate void MyDel();

    2.实例化委托:

                TestDel t = new TestDel();            
                Console.WriteLine("-----以下是简单使用委托演示--------");
                //t.MyMethod();

                ///实例化委托,用一个方法来进行实例化
                ///该方法签名要与委托签名一致
                MyDel del = new MyDel(t.MyMethod);     

    3.调用委托:      
                ///调用委托
                del();

    好了,其实委托的变化很复杂,但基本都会符合这么三个步骤,说过了,这些,再来看一下完整的代码

    namespace DelegateDemo
    {
        //声明委托
        public delegate void MyDel();
        //声明带参的委托
        public delegate void MyDel2(int num1, int num2);
        //声明带有返值的委托
        public delegate string MyDel3(string s);
    
        //声明委托用于演示匿名方法
        public delegate string ProcessString(string s);
    
        class Program
        {
            static void Main(string[] args)
            {
                #region 委托演示
                
                
                /*
                TestDel t = new TestDel();
                
                #region 简单实例化委托与调用委托
                Console.WriteLine("-----以下是简单使用委托演示--------");
                //t.MyMethod();
                ///实例化委托,用一个方法来进行实例化
                ///该方法签名要与委托签名一致
                MyDel del = new MyDel(t.MyMethod);           
                ///调用委托
                del();
    
                //C#2.0后可以这种方式实例化委托
                MyDel del4 = t.MyMethod;
                del4();
    
                //用静态方法进行实例化
                del4 = TestDel.MyStaticMethod;
                del4();
    
                //以下代码效果相同
                //MyDel2 del2 = new MyDel2(t.MyMethod);
                //del2(10, 20);
                MyDel2 del2 = t.MyMethod;
                del2(10, 20);
    
                //MyDel3 del3 = new MyDel3(t.MyMethod);
                //Console.WriteLine(del3("abc"));
                #endregion           
    
                #region 匿名方法实例化委托
                Console.WriteLine("-----以下是匿名方法演示--------");
                //用匿名方法实例化委托
                ProcessString p = delegate(string inputString) {
                    return inputString.ToUpper();
                };
                //通过委托调用匿名方法
                Console.WriteLine(p("aaaa"));
                #endregion
    
                #region 委托多播演示
    
                Console.WriteLine("-----以下是委托多播演示--------");
                MyDel mydel1 = t.MyMethod;
                MyDel mydel2 = t.MyMethod2;
                MyDel mydel3 = TestDel.MyMethod3;
                MyDel allMyDel = mydel1 + mydel2 + mydel3;
                allMyDel();
                allMyDel -= mydel3;
                allMyDel();
    
                #endregion
              
                #region 委托作为参数演示
    
                Console.WriteLine("-------以下是委托作为参数演示------");
                MyDel3 paramMyDel3 = t.MyMethod;
                TestDel.MyParamMethod("aaa", paramMyDel3);
    
                #endregion
    
                #region 委托作为返回值
    
                Console.WriteLine("---以下是委托作为返回值演示------");
                ///returnMyDel指向t.MyReturnMethod()的返回值
                MyDel3 returnMyDel = t.MyReturnMethod();
                ///returnMyDel指向t.MyMethod
                //MyDel3 returnMyDel = t.MyMethod;
    
                Console.WriteLine(returnMyDel("sssssssssssss"));
    
                #endregion
                 */
                #endregion
    
                //MyReturnDelegateTest my = new MyReturnDelegateTest();
                //my.MyTest();
                MyParamDelegateTest myParam = new MyParamDelegateTest();
                myParam.AddBooks();
                myParam.MyTest();
            }
        }
        public class TestDel
        {
            #region 普通方法
            public static void MyStaticMethod()
            {
                Console.WriteLine("My Static Method");
            }
    
            public void MyMethod()
            {
                Console.WriteLine("MyMethod");
            }
            public void MyMethod2()
            {
                Console.WriteLine("My Method 22222222222");
            }
            public static void MyMethod3()
            {
                Console.WriteLine("My Method 3333333333333");
            }
    
            public void MyMethod(int num1, int num2)
            {
                Console.WriteLine(num1+num2);
            }
            public string MyMethod(string s)
            {
                return s.ToUpper();
            }
            #endregion
    
            /// <summary>
            /// 委托作为方法参数
            /// </summary>
            /// <param name="s"></param>
            /// <param name="del3"></param>
            public static void MyParamMethod(string s, MyDel3 del3)
            {
                Console.WriteLine(del3(s));
            }
    
            /// <summary>
            /// 委托作为返回值
            /// </summary>
            /// <param name="s"></param>
            /// <returns></returns>
            public MyDel3 MyReturnMethod()
            {
                ///返回符合委托规范的方法
               return MyMethod;
            }
        }

    委托作为参数示例:

    委托作为参数
    
      public class MyParamDelegateTest
        {
            BookDB bookDB = new BookDB();
            public void AddBooks()
            {          
                bookDB.AddBook(new Book() { BookID=1,BookName="C#",Price=123,IsPaperbook=true });
                bookDB.AddBook(new Book() { BookID = 1, BookName = "C#", Price = 123, IsPaperbook = false });
                bookDB.AddBook(new Book() { BookID = 2, BookName = "ASP.Net", Price = 12, IsPaperbook = true });
                bookDB.AddBook(new Book() { BookID = 1, BookName = "ADO", Price = 23, IsPaperbook = false });
            }
            /// <summary>
            /// 用来实例化委托
            /// </summary>
            /// <param name="b"></param>
            public void TestProcessBook(Book b)
            {
                if (b.IsPaperbook)
                {
                    Console.WriteLine(b.BookName);
                }
            }
            double total = 0;
            public void TotalPrice(Book b)
            {
                total += b.Price;
            }
            public void MyTest()
            {
               
                //ProcessBook p=TestProcessBook;
                //ProcessBook p1=TotalPrice;
                //ProcessBook p2=p+p1;
                //把方法名做为参数进行传递
                bookDB.PrintBook(TestProcessBook);
                bookDB.PrintBook(TotalPrice);
                Console.WriteLine(total);
            }
    
    
        }
        public delegate void ProcessBook(Book b);
    
        public class BookDB
        {
            public List<Book> books = new List<Book>();
            public void AddBook(Book b)
            {
                books.Add(b);
            }
            public void PrintBook(ProcessBook process)
            {
                foreach (var book in books)
                {
                    process(book);
                }            
            }
        }
    
        public class Book
        {
            public int BookID { get; set; }
            public string BookName { get; set; }
            public double Price { get; set; }
            public bool IsPaperbook { get; set; }
        }

    委托作为返回值:

    委托作为返回值
    
       public delegate int MyReturnDelegate(int num1, int num2);
    
        public class MyReturnDelegateTest
        {
            public void MyTest()
            {
                MyCalcuate myCalcuate = new MyCalcuate();
                do
                {
                    Console.WriteLine("请输入符号进行以计算( + - * /)");
                    string oper = Console.ReadLine();
                    Console.WriteLine("请输入操作数1");
                    string num1 = Console.ReadLine();
    
                    Console.WriteLine("请输入操作数2");
                    string num2 = Console.ReadLine();
    
                    MyReturnDelegate myReturn = myCalcuate.Calcuate(oper);
                    int result = myReturn(int.Parse(num1), int.Parse(num2));
                    Console.WriteLine(
                        string.Format("{0}{1}{2}={3}", num1,oper,num2, result));
    
                    Console.WriteLine("您还要继续吗?Y/N");
                    //string continueFlag = Console.ReadLine();
                    //if (continueFlag.ToUpper() == "N") break;
    
                } while (Console.ReadLine().ToUpper()!="N");
            }
        }
    
        public class MyCalcuate
        {
            public MyReturnDelegate Calcuate(string oper)
            {
                MyReturnDelegate myReturn = null;
                switch (oper)
                {
                    case "+":
                        myReturn = delegate(int num1, int num2) { return num1 + num2; };
                        break;
                    case "-":
                        myReturn = delegate(int num1, int num2) { return num1 - num2; };
                        break;
                    case "*":
                        myReturn = delegate(int num1, int num2) { return num1 * num2; };
                        break;
                    case "/":
                        myReturn = delegate(int num1, int num2) { return num1 / num2; };
                        break;
                    default:
                        break;
                }
                return myReturn;
            }
        }
  • 相关阅读:
    在Linux中查找jdk路径
    AABO:自适应Anchor设置优化,性能榨取的最后一步 | ECCV 2020 Spotlight
    CSG:清华大学提出通过分化类特定卷积核来训练可解释的卷积网络 | ECCV 2020 Oral
    PIoU Loss:倾斜目标检测专用损失函数,公开超难倾斜目标数据集Retail50K | ECCV 2020 Spotlight
    简单的特征值梯度剪枝,CPU和ARM上带来4-5倍的训练加速 | ECCV 2020
    Jigsaw pre-training:摆脱ImageNet,拼图式主干网络预训练方法 | ECCV 2020
    在Windows下用VScode构造shell脚本的IDE
    Jmeter JDBC Request 使用详解
    Jmeter逻辑控制器Switch Controller的用法
    Jmeter逻辑控制器之If Controller的使用解析
  • 原文地址:https://www.cnblogs.com/bohetang/p/4039500.html
Copyright © 2011-2022 走看看