Csharp/CSharp Tutorial/delegate/delegate — различия между версиями

Материал из .Net Framework эксперт
Перейти к: навигация, поиск
м (1 версия)
 
(нет различий)

Версия 15:31, 26 мая 2010

Add both static and non-static function to a delegate

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();
   }
}
nonStaticMethod
staticMethod
nonStaticMethod
staticMethod

A simple delegate example.

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."); 
  } 
}
replaceSpaces
removeSpaces
reverseSpaces

Construct a delegate using method group conversion

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."); 
    }
}
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:


delegate ret-type name(parameter-list);

delegate is a function pointer

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;
  }
}

Delegates can refer to instance methods

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."); 
  } 
}
replaceSpaces
removeSpaces
reverseSpaces

Delegates to Instance Members

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");        
    }
}
computer: compile

Delegate with reference paramemters

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);
   }
}
Value: 12

Delegate with return values

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());
   }
}
Value: 12

named-delegate invocation

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);
        }
    }

Use a delegate to call object methods

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);
  }
}
personDescription = Price is 32 years old
M is 140 mph

uses the invocation list to calculate a factorial

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++;
    }
}