C#-委托(C#高级编程笔记)

来源:互联网 发布:基于bpr算法的商品推荐 编辑:程序博客网 时间:2024/05/29 16:51
委托(C#高级编程笔记) p153
与C不同的是,.NET的委托是类型安全的.C中的函数指针只不过是指向一个存储单元的指针,我们无法说出这个指针实际指向什么,而参数和返回类型就更无从知晓了.
实际上,”定义一个委托”是指”定义一个新类”,委托的实现派生于System.MulticastDelegate, MulticastDelegate又派生于System.Delegate.
如何在C#中使用委托:
例1.
 
public class MyClass
{
    
public delegate string delegateTest(string dval1,string dval2);
    
public string ConnectString(string val1,string val2)
    
{
        
return val1+val2;
    }

    
public static void Main()
    
{
        MyClass mc 
= new MyClass();
        delegateTest t 
= new delegateTest(mc.ConnectString);
        Console.WriteLine(t(
"Hello"," China!"));
    }

}
匿名方法:
匿名方法定义委托时与前面没有区别,只是在实例化时,就不同了.匿名方法的优点是减少了开销,方法仅在由委托使用时才定义.
使用匿名方法要遵循的两个规则:
1、             在匿名方法中不能使用跳转语句跳到该匿名方法体
2、             反之,匿名方法体外的语句也不能跳转到匿名方法体.
例2.
public class MyClass
{
    
public delegate string nonameTest(string dval1,string dval2);//匿名委托
    public static void Main()
    
{
        nonameTest nonameT 
= delegate(string val1,string val2)//注意实例化时的区别
        {
            
return val1+val2;
        }
//注意分号
        Console.WriteLine(nonameT("Hello"," China"));
        Console.ReadLine();
    }

}
 
例3中,将委托的实例放在数组中是可以的.该数组的每一个元素都执行不同的操作,这样我们就可以在循环中调用不同方法了.
例3.
 
public class MyClass
{    
    
public static double doubleCal(double val) //静态
    {
        
return val * 2;
    }

    
public static double squareCal(double val) //静态
    {
        
return val * val;
    }
    
    
public delegate double MathCal(double val);
    
public static void Main()
    
{        
        MathCal[] uMath 
= new MathCal[]{new MathCal(doubleCal),new MathCal(squareCal)};//委托数组
        for(int i = 0;i<uMath.Length;i++)
        
{
            Console.WriteLine(uMath[i](
4));
        }

        Console.ReadLine();
    }

}
 
BubbleSorter示例P161
冒泡算法
 
public class MyClass
{        
    
public int[] Sort(int[] arr)
    
{
        
int[] array = arr;
        
for(int i = 0;i < array.Length -1;i++)
        
{
            
for(int j = i+1;j < array.Length;j++)
            
{                
                
if(array[j]<array[i])
                
{
                    
int temp = array[i];
                    array[i] 
= array[j];
                    array[j] 
= temp;
                }
                
            }

        }

        
return array;
    }

    
public static void Main()
    
{        
        MyClass mc 
= new MyClass();
        
int[] arr = {0,2,5,3,7,8};
        arr 
= mc.Sort(arr);
        
for(int i=0;i<arr.Length;i++)
        
{
            Console.Write(arr[i]);
        }

        Console.ReadLine();
    }

}
 
自己写的一个委托例子,只是用来显示用法
自总结:
使用到委托函数的特点,看ShowFinded,它将参数1(一个类数组)传递进第二个(委托)参数(其实是方法)中进行处理.我感觉就是如果要在函数中处理函数,那需要使用到委托(就是回调,就是函数指针嘛)
例4.
 
public class MyClass
{
    
public static int cnt = 0;
    
public delegate int delegateFind(object[] id,string area);//委托(按地区查找)
    
    
//此函数处理过程:将类数组当参数传给委托dFind(其实就是进入Find),得到查询人数,再输出.
    public static void ShowFinded(object[] id,delegateFind dFind,string area)//静态(输出地区分部人数)
    {
        
int showCnt = dFind(id,area);
        Console.WriteLine(area
+"人共有"+showCnt+"名.");
    }

    
    
public int Find(object[] id,string area)
    
{
        
for(int i = 0; i < id.Length; i++)
        
{
            
if(((Identify)id[i]).area == area)
            
{
                MyClass.cnt 
++;
            }

        }

        
return MyClass.cnt;
    }
    
    
    
public static void Main()
    
{
        Identify[] id 
= new Identify[]{    new Identify("张三",22,"河北"),new Identify("李四",25,"江苏"),
                                                    
new Identify("王五",20,"山东"),new Identify("小强",27,"江苏"),
                                                    
new Identify("阿扁",23,"火星"),new Identify("布什",13,"火星")        }
;
        MyClass mc 
= new MyClass();                                
        delegateFind dFind 
= new delegateFind(mc.Find);    
        
        MyClass.ShowFinded(id,dFind,
"江苏"); //主处理函数,静态
    }

}


public class Identify
{
    
public string name;
    
public int age;
    
public string area;
    
    
public Identify(string name,int age,string area)
    
{
        
this.name = name;
        
this.age = age;
        
this.area = area;
    }

}
多播委托
       调用多播委托,就可以按顺序连续调用多个方法(注意,如果用于事件,则是无序的),为此,多播委托的返回值必然是void.
例5.
public class MyClass
{    
    
public static void doubleCal(double val) //返回值void
    {
        Console.WriteLine(
"double_operate value is "+val * 2);
    }

    
public static void squareCal(double val) //返回值void
    {
        Console.WriteLine(
"square_operate value is "+val * val);
    }
    
    
public delegate void MathCal(double val); //返回值void
    public static void Main()
    
{        
        MathCal mc 
= new MathCal(doubleCal);
        mc 
+= new MathCal(squareCal);    // +=
//        MathCal mc1 = new MathCal(doubleCal);
//        MathCal mc2 = new MathCal(squareCal);        
//        MathCal mc = mc1 + mc2; // +
        mc(3);
        Console.ReadLine();
    }

}

//output:
//            double_operate value is 6
//            square_operate value is 9
 
 
原创粉丝点击