Csharp/CSharp Tutorial/delegate/delegate

Материал из .Net Framework эксперт
Версия от 15:19, 26 мая 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Add both static and non-static function to a delegate

<source lang="csharp">using System;

delegate void FunctionToCall(); class MyClass {

  public void nonStaticMethod()
  {
     Console.WriteLine("nonStaticMethod");
  }
  public static void staticMethod()
  {
     Console.WriteLine("staticMethod");
  }

} class MainClass {

  static void Main()
  {
     MyClass t = new MyClass();    
     FunctionToCall functionDelegate;
     functionDelegate = t.nonStaticMethod;           
     functionDelegate += MyClass.staticMethod;
     functionDelegate += t.nonStaticMethod;
     functionDelegate += MyClass.staticMethod;
     functionDelegate();
  }

}</source>

nonStaticMethod
staticMethod
nonStaticMethod
staticMethod

A simple delegate example.

<source lang="csharp">using System;

delegate string StrMod(string str);

class MainClass {

 static string replaceSpaces(string a) { 
   Console.WriteLine("replaceSpaces"); 
   return a; 
 }  

 static string removeSpaces(string a) { 
   Console.WriteLine("removeSpaces"); 
   return a; 
 }  

 static string reverse(string a) { 
   Console.WriteLine("reverseSpaces"); 
   return a; 
 } 
    
 public static void Main() {  
   StrMod strOp = new StrMod(replaceSpaces); 
   string str; 

   str = strOp("This is a test."); 
     
   strOp = new StrMod(removeSpaces); 
   str = strOp("This is a test."); 

   strOp = new StrMod(reverse); 
   str = strOp("This is a test."); 
 } 

}</source>

replaceSpaces
removeSpaces
reverseSpaces

Construct a delegate using method group conversion

<source lang="csharp">using System;

delegate string StrMod(string str);

class MainClass {

 static string replaceSpaces(string a) { 
   Console.WriteLine("replaceSpaces"); 
   return a; 
 }  

 static string removeSpaces(string a) { 
   Console.WriteLine("removeSpaces"); 
   return a; 
 }  

 static string reverse(string a) { 
   Console.WriteLine("reverseSpaces"); 
   return a; 
 } 
    
   public static void Main() {  
     
     StrMod strOp = replaceSpaces; // use method group conversion 
     string str; 
    
     // Call methods through the delegate. 
     str = strOp("This is a test."); 
   
         
     strOp = removeSpaces; // use method group conversion 
     str = strOp("This is a test."); 
   
    
     strOp = reverse; // use method group converison 
     str = strOp("This is a test."); 
   }

}</source>

replaceSpaces
removeSpaces
reverseSpaces

Define a delegate with no return value and no parameters

  1. A delegate is an object that can refer to a method.
  2. The method referenced by delegate can be called through the delegate.
  3. A delegate in C# is similar to a function pointer in C/C++.
  4. The same delegate can call different methods.
  5. A delegate is declared using the keyword delegate.

The general form of a delegate declaration:


<source lang="csharp">delegate ret-type name(parameter-list);</source>

delegate is a function pointer

<source lang="csharp">using System; class MainClass {

 delegate int MyDelegate(string s);
 static void Main(string[] args)
 {
   MyDelegate Del1 = new MyDelegate(DoSomething);
   MyDelegate Del2 = new MyDelegate(DoSomething2);
   string MyString = "Hello World";
   Del1(MyString);
   Del2(MyString);
 }
 static int DoSomething(string s)
 {
   Console.WriteLine("DoSomething");
   
   return 0;
 }
 static int DoSomething2(string s)
 {
     Console.WriteLine("DoSomething2");
   return 0;
 }

}</source>

Delegates can refer to instance methods

<source lang="csharp">using System;

delegate string StrMod(string str);

class StringOps {

 public static string replaceSpaces(string a) { 
   Console.WriteLine("replaceSpaces"); 
   return a; 
 }  

 public static string removeSpaces(string a) { 
   Console.WriteLine("removeSpaces"); 
   return a; 
 }  

 public static string reverse(string a) { 
   Console.WriteLine("reverseSpaces"); 
   return a; 
 } 

}

class MainClass {

 public static void Main() {  

   // Initialize a delegate. 
   StrMod strOp = new StrMod(StringOps.replaceSpaces); 
   string str; 

   // Call methods through delegates. 
   str = strOp("This is a test."); 
     
   strOp = new StrMod(StringOps.removeSpaces); 
   str = strOp("This is a test."); 

   strOp = new StrMod(StringOps.reverse); 
   str = strOp("This is a test."); 
 } 

}</source>

replaceSpaces
removeSpaces
reverseSpaces

Delegates to Instance Members

<source lang="csharp">using System; public class Machine {

   string name;
   public Machine(string name)
   {
       this.name = name;
   }    
   public void Process(string message)
   {
       Console.WriteLine("{0}: {1}", name, message);
   }

} class MainClass {

   delegate void ProcessHandler(string message);
   
   public static void Main()
   {
       Machine aMachine = new Machine("computer");
       ProcessHandler ph = new ProcessHandler(aMachine.Process);
       
       ph("compile");        
   }

}</source>

computer: compile

Delegate with reference paramemters

<source lang="csharp">using System; delegate void FunctionToCall(ref int X); class MainClass {

  public static void Add2(ref int x) { 
      x += 2; 
  }
  
  public static void Add3(ref int x) { 
      x += 3; 
  }
  static void Main(string[] args)
  {
     FunctionToCall functionDelegate = Add2;
     functionDelegate += Add3;
     functionDelegate += Add2;
     int x = 5;
     functionDelegate(ref x);
     Console.WriteLine("Value: {0}", x);
  }

}</source>

Value: 12

Delegate with return values

<source lang="csharp">using System; delegate int FunctionToCall(); class MainClass {

  static int IntValue = 5;
  public static int Add2() {
      IntValue += 2;
      return IntValue;
  }
  public static int Add3() {
     IntValue += 3;
     return IntValue;
  }
  static void Main()
  {
     FunctionToCall functionDelegate = Add2;
     functionDelegate += Add3;
     functionDelegate += Add2;
     Console.WriteLine("Value: {0}", functionDelegate());
  }

}</source>

Value: 12

named-delegate invocation

<source lang="csharp">using System; using System.Collections.Generic; using System.Text;

   class Program
   {
       delegate void MessagePrintDelegate(string msg);
       static void Main(string[] args)
       {
           MessagePrintDelegate mpd = new MessagePrintDelegate(PrintMessage);
           LongRunningMethod(mpd);
       }
       static void LongRunningMethod(MessagePrintDelegate mpd)
       {
           for (int i = 0; i < 99; i++)
           {
               if (i % 25 == 0)
               {
                   mpd(string.Format("Progress Made. {0}% complete.", i));
               }
           }
       }
       static void PrintMessage(string msg)
       {
           Console.WriteLine("[PrintMessage] {0}", msg);
       }
   }</source>

Use a delegate to call object methods

<source lang="csharp">using System; public delegate string DelegateDescription(); public class Person {

 private string name;
 private int age;
 public Person(string name, int age)
 {
   this.name = name;
   this.age = age;
 }
 public string NameAndAge()
 {
   return(name + " is " + age + " years old");
 }

} public class Employee {

 private string name;
 private int number;
 public Employee(string name, int number)
 {
   this.name = name;
   this.number = number;
 }
 public string MakeAndNumber()
 {
   return(name + " is " + number + " mph");
 }

} class MainClass {

 public static void Main()
 {
   Person myPerson = new Person("Price", 32);
   DelegateDescription myDelegateDescription = new DelegateDescription(myPerson.NameAndAge);
   string personDescription = myDelegateDescription();
   Console.WriteLine("personDescription = " + personDescription);
   Employee myEmployee = new Employee("M", 140);
   myDelegateDescription = new DelegateDescription(myEmployee.MakeAndNumber);
   string d = myDelegateDescription();
   Console.WriteLine(d);
 }

}</source>

personDescription = Price is 32 years old
M is 140 mph

uses the invocation list to calculate a factorial

<source lang="csharp">using System; public delegate int IncrementDelegate(ref short refCount); public class Factorial {

   public static void Main() {
       IncrementDelegate[] values = { Incrementer, Incrementer,Incrementer, Incrementer, Incrementer};
       IncrementDelegate del = (IncrementDelegate)
       IncrementDelegate.rubine(values);
       long result = 1;
       short count = 1;
       foreach (IncrementDelegate number in del.GetInvocationList()) {
           result = result * number(ref count);
       }
       Console.WriteLine("{0} factorial is {1}", del.GetInvocationList().Length, result);
   }
   public static int Incrementer(ref short refCount) {
       return refCount++;
   }

}</source>