委托

1.委托能用来做什么

一个笼统的准则:当要把方法传给其他方法时,需要使用委托。比如下面几个场景:

a.启动线程和任务

          即Thread类的构造函数必须带有一个参数,该参数定义线程调用的方法。

    Thread t = new Thread(new ThreadStart(Go));//public static GO(){}

b.设计模式中的简单工厂模式。

    向一个方法中传递一个子类的方法。

c.事件。

    一般通知代码发生了什么事件。GUI编程主要处理事件。在引发事件时,运行库需要知道应执行哪个方法。

    这就需要处理事件的方法作为一个参数传递给委托。

2.如何自定义委托

 声明一个委托类型,他的实例应用一个方法,该方法获取一个int类型的参数,返回值void

public delegage void Feeback(int num);

理解委托的一个要点是他们的安全性非常高,在定义委托时候,必须给出他的方法的签名和返回类型的全部细节

理解委托的比较好的方式是把委托当做这样的一件事情,给他的方法的签名和返回值类型指定名称

3..Net默认的委托类型有哪几种

1.Action<T>

  泛型Action<T>委托表示引用一个void返回类型的方法。这个委托类存在16种重载方法。

  例如Action<in T1,In T2>调用没有参数的方法

2.Func<T>

  Func<T>调用带返回类型的方法。有16种重载方法。

  例如Func<out TResult>委托类型可以调用带返回类型且无参数的方法,

  Func<in T,out TResult>委托类型调用带有4个参数和一个返回类型的方法。

3.等等

4.怎样使用委托

// 声明一个委托类型,它的实例引用一个方法,该方法获取一个int参数,返回string
    public delegate String myMethodDelegate(int myInt);
    // 定义一些方法给委托变量引用
    public class mySampleClass
    {
        // 定义一个实例方法
        public String myStringMethod(int myInt)
        {
            if (myInt > 0)
                return ("positive");
            if (myInt < 0)
                return ("negative");
            return ("zero");
        }
        // 定义一个静态方法
        public static String mySignMethod(int myInt)
        {
            if (myInt > 0)
                return ("+");
            if (myInt < 0)
                return ("-");
            return ("");
        }
    }
    public static void Main()
    {
        // 给每个方法都创建一个委托实例
        // 对于实例方法,mySC必须提供
        //   对于静态方法,只需要指定类的名字
        mySampleClass mySC = new mySampleClass();
        myMethodDelegate myD1 = new myMethodDelegate(mySC.myStringMethod);
        myMethodDelegate myD2 = new myMethodDelegate(mySampleClass.mySignMethod);
        // 调用委托
        Console.WriteLine("{0} is {1}; use the sign \"{2}\".", 5, myD1(5), myD2(5));
        Console.WriteLine("{0} is {1}; use the sign \"{2}\".", -3, myD1(-3), myD2(-3));
        Console.WriteLine("{0} is {1}; use the sign \"{2}\".", 0, myD1(0), myD2(0));
    }

5.什么事匿名方法

//匿名方法,例1
        Func<int, int> anon = delegate(int i)
        {
            i = i+1;
            return i;
        };
        //输出2
        Console.WriteLine(anon(1));
         
        //匿名方法,例2
        Action<int> anon2 = delegate(int i)
        {
            i = i + 1;
        };
        //输出2
        Console.WriteLine(anon(1));

6.Lambda表达式怎么传参

Lambda表达式有几种定义参数的方式。

1.只有一个参数,只写出参数名就足够了。

如下面的例子:

定义了一个泛型委托,输入参数是一个string类型,返回一个string类型,

lambda表达式:s=>s.Replace('a,b')

委托引用的方法名:oneParam

传入参数:abc

打印结果:bbc

1 Func<string, string> oneParam = s => s.Replace('a', 'b');
2 Console.WriteLine(oneParam("abc"));
3 Console.ReadKey();

2.如果委托使用多个参数,就把参数名放在小括号中。

如下面的例子:

定义了一个泛型委托,输入参数是两个int类型(可以给小括号中的变量名添加参数类型),返回一个int类型,

lambda表达式:(i, j) => i*j

委托引用的方法名:twoParam

传入参数:24

打印结果:8

1 Func<int, int, int> twoParam = (i, j) => i*j;
2 Console.WriteLine(twoParam(2,4));

7.Lambda多行代码怎么写

添加大括号,如果需要返回值,则必须添加return语句

Func<int, int, int> test = (i, j) => 
{ 
    i = i + 1;
    i = i * j;
    return i;
};
Console.WriteLine(test(2, 4));

8..什么是闭包

通过Lambda表达式可以访问Lambda表达式块外部的变量,这成为闭包。

当引用外部变量时,需要注意,外部变量变化时,lambda表达式的结果也可能会随着外部变量变化而变化。

如下面的例子:

1 int y = 5;
2 Func<int, int> lambda = x => x + y;
3 Console.WriteLine(lambda(1));
4 y = 10;
5 Console.WriteLine(lambda(1));

第一次打印出6,第二次打印出11

 public delegate void ProgressPeporter(int percentComplete);

    public class Utility
    {
        public static void Match(ProgressPeporter p)
        {
            if (p!=null)
            {
                for (int i = 0; i <= 10; i++)
                {
                    p(i*10);
                    Thread.Sleep(100);
                }
            }
        }
    }
    class Program
    {
        static  void Main(string[] args)
        {
            ProgressPeporter p = new ProgressPeporter(WriteProgressToConsole);
            p += WriteProgressToFile;
            Utility.Match(p);
            Console.WriteLine("Done");
            Console.ReadKey();
        }

        static void WriteProgressToConsole(int percnetComplete)
        {
            Console.WriteLine(percnetComplete+"%");
        }

        static void WriteProgressToFile(int percentComplete)
        {
           File.AppendAllText("progress.txt",percentComplete+"%");
        }
    
    }



你可能感兴趣的:(委托)