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;
    }
    }
  • 相关阅读:
    【ARTS】打卡第七周
    【ARTS】打卡第六周
    【ARTS】打卡第五周
    【leetcode】 438. Find All Anagrams in a String
    【ARTS】打卡第四周
    【ARTS】打卡第三周
    【leetcode】 11. Container With Most Water
    【ARTS】打卡第二周
    【ARTS】打卡第一周
    深度VS广度——谈谈对测试职业的一些思考
  • 原文地址:https://www.cnblogs.com/hanmos/p/2030986.html
Copyright © 2011-2022 走看看