程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> C#基礎之委托

C#基礎之委托

編輯:C#基礎知識

  委托常常和事件在一起使用,可以理解委托是方法的容器,事件則是委托的另一種表現形式。委托和事件雖然寫得還比較多,不過也只是用的熟練而已,趁周末沒課好好鞏固下基礎,一點一點積累吧。

1.一個簡單的小例子

    class Program
    {
        static void Main(string[] args)
        {
            People people = new People();
            people.StartEat("吃");
            Console.ReadLine();
        }
    }
    class People
    {
        public void EatApple(string s)
        {
            Console.WriteLine(s+"蘋果");
        }
        public void EatPear(string s)
        {
            Console.WriteLine(s+"梨子");
        }
        public void StartEat(string str)
        {
            EatApple(str);
        }
    }

上面的代碼應該很好理解,但是在StartEat方法並不知道什麼時候該調用哪個方法進行輸出,因此在調用之前還需要定義一個枚舉EatWhat來進行判斷,也就是StartEat(string str,EatWhat eatWhat)。傳入的eatWhat枚舉判斷是吃蘋果還是梨子。但是這種寫法擴展性太差了,如果再加一個吃西瓜的方法,那麼還要更新枚舉,這樣反復的增加方法和枚舉顯然不是一個很好的做法。

  顯然這裡要使用委托,為什麼要使用委托?最本質的原因是利用委托可使StartEat得到一個參數,而這個參數是方法,這樣我們想調用什麼就可以調用什麼了。

class Program
    {
        static void Main(string[] args)
        {
            People people = new People();
            people.StartEat("吃", people.EatApple);
            people.StartEat("吃", people.EatPear);
            Console.ReadLine();
        }
    }
    public delegate void EatDelegate(string name);
    class People
    {
        public void EatApple(string s)
        {
            Console.WriteLine(s+"蘋果");
        }
        public void EatPear(string s)
        {
            Console.WriteLine(s + "梨子");
        }
        public void StartEat(string str,EatDelegate eatDelegate)
        {
            eatDelegate(str);
        }
 

}

2.多播委托

  委托的特殊之處在於,我們以前定義的所有對象都包含數據,而委托包含的只是方法的地址。在上面例子的基礎上,我們還可以實現多播委托。多播委托就是講多個方法賦給同一個委托,當調用這個委托的時候,將依次調用其綁定的方法。下面是對Program類的改動。

    class Program
    {
        static void Main(string[] args)
        {
            People people = new People();
            EatDelegate del = people.EatPear;
            del += people.EatApple;
            people.StartEat("吃", del);
            //既然可以對委托添加方法,那麼也可以對委托取消方法的綁定
            del -= people.EatPear;
            Console.ReadLine();
        }
    }

 3.委托和事件

  在上面的例子中,我們給StartEat方法傳參時需要傳入2個參數,而且還需要在Main方法中得到委托對象。因此我們可以將委托封裝到People類裡面,使傳參時只傳入一個參數,這就是用到了封裝的思想。

 class Program
    {
        static void Main(string[] args)
        {
            People people = new People();
            people.del = people.EatPear;
            people.del += people.EatApple;
            people.StartEat("吃");
            Console.ReadLine();
        }
    }
    class People
    {
        public EatDelegate del;
        public void EatApple(string s)
        {
            Console.WriteLine(s+"蘋果");
        }
        public void EatPear(string s)
        {
            Console.WriteLine(s + "梨子");
        }
        public void StartEat(string str)
        {
            if (del != null)
            {
                del(str);
            }
        }
    }

現在我們的委托對象和一般的變量沒有什麼區別,外部類訪問到People對象就可以拿到這個委托變量。假如現在在類裡面聲明一個字段,一般我們會封裝字段采用屬性。同樣的,對於委托我們也要封裝,這樣在類的內部,委托變量總是私有,但是在外部,依舊可以使用+=和-=的訪問操作。接下來我們對代碼進行改寫。

 static void Main(string[] args)
        {
            People people = new People();
            //現在已經不能使用=來給事件對象賦值,而只能使用+=和-=來進行操作
            people.eventDelegate += people.EatApple;
            people.eventDelegate+=people.EatPear;
            people.StartEat("吃");
            Console.ReadLine();
        }
    }
    class People
    {
        //簡單點理解,事件其實就可以理解為一個封裝了委托的變量
        //如果去看代碼執行的源碼,會發現eventDelegate變量,其實就是一個委托對象,只不過它是私有的,修飾符為private
        //這個委托變量有2個方法 ,且只有2個方法,+=對應addon,-=對應於removeon方法。
        public event EatDelegate eventDelegate;
        public void EatApple(string s)
        {
            Console.WriteLine(s+"蘋果");
        }
        public void EatPear(string s)
        {
            Console.WriteLine(s + "梨子");
        }
        public void StartEat(string str)
        {
            eventDelegate(str);
        }
    }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved