栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C#学习(9)----委托

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#学习(9)----委托

委托很像C语言的函数指针,是函数指针的升级版。

先贴上一段C语言的函数指针。

#include 

typedef int(*Calcu)(int x,int y);

int Add(int x,int y){
	return x+y;
}

int Sub(int x,int y){
	return x-y;
}

int aha(int m,int n,Calcu s){
	return s(m,n);
}

int main(){
	int m=100,n=10;
	Calcu x=Add;
	Calcu y=Sub;
	printf("%dn",(*x)(1,2)); //或:x(1,2)即可 
	int result1=aha(m,n,x);
	int result2=aha(m,n,y);
	printf("%d %d",result1,result2);
	return 0;
}

函数指针记录了函数的地址,可以直接通过他来直接调用函数,或者作为参数传入其他函数。委托也有这种作用。

委托是函数指针的升级版,它可以通过某些限定条件,来指向某些目标方法,帮助我们完成对方法的间接调用。

委托是一个类,C#已经帮我们定义了很多种委托。其中,Action和Function是最常见的委托。

//Action委托,只接受返回值和参数都是空的方法
namespace ConsoleAppPractice
{
    public delegate bool Compare(int x, int y);
    class Program
    {
        static void Main()
        {
            Test test = new Test();
            Action action = new Action(test.laugh);//此处只写函数名就行。
            action();
            action.Invoke();//两种调用方法
        }
    }
    class Test
    {
        public void laugh()
        {
            Console.WriteLine("哈哈!");
        }
    }
}
//使用Func委托:Func是泛类型,尖括号中接受的参数,第一个是方法返回值,后面的是方法参数
namespace ConsoleAppPractice
{
    public delegate bool Compare(int x, int y);
    class Program
    {
        static void Main()
        {
            Test test = new Test();
            Func func = new Func(test.Add);
            int result = func(1, 2);
            Console.WriteLine(result);
        }
    }
    class Test
    {
        public int Add(int x,int y)
        {
            return x + y;
        }
    }
}

如果要自定义委托:

委托是类,是一种数据类型,故虽然C#支持类的嵌套,但是最好还是放在与其他类并列的名称空间体里。

委托的声明方式不同于其他的类,主要是为了照顾可读性和C的传统。

委托定义需与方法兼容。

下面的冒泡排序一例便给出了自定义委托类型,并且以模板方法方式使用的例子:

namespace ConsoleAppPractice
{
    public delegate bool Compare(int x, int y);

    class Program
    {
        static void Main()
        {
            int[] array = new int[] { 1, 2, 6, 4, 2, 8, 3, 9 };
            string str = Console.ReadLine();
            int choice = int.Parse(str);
            Compare compare1 = new Compare(Comparasion.compare1);
            Compare compare2 = new Compare(Comparasion.compare2);
            switch (choice)
            {
                case 1:
                    BubbleSort.BubbleSorting(array, array.Length, compare1);
                    break;
                default:
                    BubbleSort.BubbleSorting(array, array.Length, compare2);
                    break;
            }
            foreach (var item in array)
            {
                Console.WriteLine(item);
            }
        }
    }
    class Comparasion
    {
        public static bool compare1(int x,int y)
        {
            return x > y;
        }
        public static bool compare2(int x,int y)
        {
            return x < y;
        }
    }
    class BubbleSort
    {
        private bool isWEN = true;
        public bool IsWEN
        {
            get { return isWEN = true;; }
        }
        public static void BubbleSorting(int[]array,int length,Compare compare)
        {
            for (int i = length-1; i >= 0; i--)
            {
                for (int j = 0; j < i; j++)
                {
                    if (compare(array[j+1], array[j]))
                    {
                        int temp = array[j];
                        array[j] = array[j+1];
                        array[j+1] = temp;
                    }
                }
            }
        }
    }
}

委托的使用方法:

委托一般用于把方法当作一个参数传给另一个函数。

正确使用1:“模板方法”,借用指定的外部方法来产生结果。

namespace ConsoleAppPractice
{
    public delegate bool Compare(int x, int y);
    class Program
    {
        static void Main()
        {
            Func createPizza = new Func(ProductFactory.CreatePizza);
            Func createToy = new Func(ProductFactory.CreateToy);
            Box boxPizza = new Box();
            Box boxToy = new Box();
            boxPizza = Wrap.WrapProduct(createPizza);
            boxToy = Wrap.WrapProduct(createToy);
            Console.WriteLine(boxPizza.product.Name);
            Console.WriteLine(boxToy.product.Name);
        }
    }
    
    class Product
    {
        public string Name { get; set; }
    }

    class Box
    {
        public Product product { get; set; }
    }

    class ProductFactory
    {
        public static Product CreatePizza()
        {
            Product product = new Product();
            product.Name = "Pizza";
            return product;
        }
        public static Product CreateToy()
        {
            Product product = new Product();
            product.Name = "Toy";
            return product;
        }
    }

    class Wrap
    {
        public static Box WrapProduct(Func create)
        {
            Box box = new Box();
            box.product = create();
            return box;
        }
    }
}

在wrap函数中,就是依照传入的create方法的不同,来创造出不同的产品。当产品数增多时,依然只需要这一个方法。因而可以减少代码长度,提高可读性。

正确使用2:“回调方法”,需要你时才调用

namespace ConsoleAppPractice
{
    public delegate bool Compare(int x, int y);
    class Program
    {
        static void Main()
        {
            Func createPizza = new Func(ProductFactory.CreatePizza);
            Func createToy = new Func(ProductFactory.CreateToy);
            Action log = new Action(Log.CreateLog);
            
            Box boxPizza = Wrap.WrapProduct(createPizza,log);
            Box boxToy = Wrap.WrapProduct(createToy,log);

            Console.WriteLine(boxPizza.product.Name);
            Console.WriteLine(boxToy.product.Name);
        }
    }

    class Product
    {
        public string Name { get; set; }
        public int Price { get; set; }
    }

    class Box
    {
        public Product product { get; set; }
    }

    class ProductFactory
    {
        public static Product CreatePizza()
        {
            Product product = new Product();
            product.Name = "Pizza";
            product.Price = 3;
            return product;
        }
        public static Product CreateToy()
        {
            Product product = new Product();
            product.Name = "Toy";
            product.Price = 900;
            return product;
        }
    }

    class Wrap
    {
        public static Box WrapProduct(Func create,Action log)
        {
            Box box = new Box();
            box.product = create();
            if (box.product.Price > 50)
            {
                Console.WriteLine("The product is {0}.",box.product.Name);
                log();
            }
            return box;
        }
    }

    class Log
    {
        public static void CreateLog()
        {
            Console.WriteLine("Wrap-day is {0}",DateTime.Now);
        }
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/629966.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号