C#编程之委托

C#编程之委托

一、委托的分类

1、Func:可以传递0或者多到16个参数类型,还可以传递一个返回值,并且返回值要放在参数最后。(有返回值)

2、Action:可以传递0或者多到16个参数类型,但是不可以传递返回值。(无返回值)

二、委托的定义

如果我们要把方法当做参数来传递的话,就要用到委托。简单来说委托是一个类型,这个类型可以赋值一个方法的引用。

三、Func的使用案例

方法:

/// <summary>
/// 从服务器下载文件,并将文件保存到本地
/// </summary>
/// <param name="url"></param>
/// <param name="parameters"></param>
/// <param name="method"></param>
/// <param name="filePath"></param>
/// <param name="fileName"></param>
/// <returns></returns>
public static string DownFile2HTTP2(string url, IDictionary<string, string> parameters, string method, string filePath, string fileName)
{
    string path = filePath + "\\" + fileName;
    if (method.ToLower() == "post")
    {
        FileStream fileStream = null;
        HttpWebRequest req = null;
        HttpWebResponse rsp = null;
        System.IO.Stream reqStream = null;
        try
        {
            fileStream = new FileStream(path, FileMode.Create);
            req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = method;
            req.KeepAlive = false;
            req.ProtocolVersion = HttpVersion.Version10;
            req.Timeout = 5000;
            req.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
            byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(parameters, "utf8"));
            reqStream = req.GetRequestStream();
            reqStream.Write(postData, 0, postData.Length);
            rsp = (HttpWebResponse)req.GetResponse();
            byte[] data = new byte[1024];
            while (true)
            {
                int length = reqStream.Read(data, 0, data.Length);
                if (length == 0)
                {
                    break;
                }
                else
                {
                    fileStream.Write(data,0,length);
                }
            }
            return "";
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
        finally
        {
            if (reqStream != null) reqStream.Close();
            if (rsp != null) rsp.Close();
            if (fileStream != null) fileStream.Close();
        }
    }
    else
    {
        FileStream fileStream = new FileStream(path,FileMode.Create);
        //创建请求
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "?" + BuildQuery(parameters, "utf8"));


        //GET请求
        request.Method = "GET";
        request.ReadWriteTimeout = 5000;
        request.ContentType = "text/html;charset=UTF-8";
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream myResponseStream = response.GetResponseStream();
        //写入文件
        byte[] data = new byte[1024];
        while (true)
        {
            int length = myResponseStream.Read(data, 0, data.Length);
            if (length == 0)
            {
                break;
            }
            else
            {
                fileStream.Write(data, 0, length);
            }
        }
        return "";
    }
}

使用案例:

IDictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("name", "test");

//定义Func委托
Func<string, IDictionary<string, string>, string, string, string, string> func = HttpTools.DownFile2HTTP2;
//使用Func委托,IAsyncResult为Func的返回值类,用于判断方法是否执行完毕,以及后面获取返回值
IAsyncResult iAsyncResult = func.BeginInvoke("http://localhost:8080/web/", parameters, "GET", @"E:\work\HttpTest", "数据测试1.xls", null, null);
//通过死循环判断方法是否已执行完毕,验证方法是否完成
while (true)
{
    if (iAsyncResult.IsCompleted)
    {
        break;
    }
}
//通过EndInvoke方法获取返回值,参数类型为开始执行委托时的返回值
string result = func.EndInvoke(iAsyncResult);

四、Aciton的使用案例

方法:

 private void GetMessage(string name,int a,int b)
 {
     int sum = a + b;
     Debug.WriteLine(name + ":  " + sum);
 }

案例:

//定义Action委托
Action<string,int,int> action = GetMessage;
//使用Action委托
IAsyncResult result = action.BeginInvoke("zhangsan", 10, 12,null,null);
//通过死循环判断方法是否已执行完毕,验证方法是否完成
while (true)
{
    if (result.IsCompleted)
    {
        break;
    }
}

五、委托的其他使用案例之排序


//类的定义

class Employee{
public Employ(string name,decimal salary){
this.Name = name;
this.Salary = salary;
}
public string Name{get;private set;}
public decimal Salary{get;private set;}
public static bool CompareSalary(Employee e1,Employee e2){
return e1.salary>e2.salary;
}
}



//排序方法

public static void Sort<T>( List<T> sortArray,Func<T,T,bool> comparision ){
bool swapped = true;
do{
swapped = false;
for(int i=0;i<sortArray.Count-1;i++){
if(comparision(sortArray[i+1],sortArray[i])){
T temp = sortArray[i];
sortArray[i]=sortArray[i+1];
sortArray[i+1]=temp;
swapped = true;
}
}
}while(swapped);
}



//使用案例

static void Main(){
Employee[] employees = {
new Employee("Bunny",20000),
new Employee("Bunny",10000),
new Employee("Bunny",25000),
new Employee("Bunny",100000),
new Employee("Bunny",23000),
new Employee("Bunny",50000),
};
Sort(employees,Employee.CompareSalary);
//输出

}

五、多播委托

前面使用的委托都只包含一个方法的调用,但是委托也可以包含多个方法,这种委托叫做多播委托。使用多播委托就可以按照顺序调用多个方法,多播委托只能得到调用的最后一个方法的结果,一般我们把多播委托的返回类型声明为void。


Action action1 = Test1;
action2+=Test2;
action2-=Test1;


多播委托包含一个逐个调用的委托集合,如果通过委托调用的其中一个方法抛出异常,整个迭代就会停止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值