深入解析C#编程中泛型委托的使用
在看泛型委托之前还需要先了解委托的概念。
这里讲的委托有两种类型一种是有返回值的,另一种是事件委托。
//定义有返回值的委托 public delegate string genricdelegate<t, s>(t title, s author); //定义事件委托。 public delegate void genricdelegateenent<e,p>(e name,p address); public class genericdelegateclass<v,f> { //声明委托 public genricdelegate<v, f> gdelevalue; //声明事件委托 public event genricdelegateenent<v, f> gdevent = null; public string getvalues(v title, f author) { //调用委托 return gdelevalue(title, author); } public genericdelegateclass() { } public void invokeevent(v name, f address) { if (gdevent != null) { //调用委托 gdevent(name, address); } } }
上面我们定义及调用了泛型委托,接下来就来梆定委托。
private void btndelegate_click(object sender, eventargs e) { genericdelegateclass<string, string> gd = new genericdelegateclass<string, string>(); //将delegatereturn事件梆定给gdelevalue gd.gdelevalue = new genricdelegate<string, string>(delegatereturn); //将genericevent事件梆定给gdevent gd.gdevent += new genricdelegateenent<string, string>(genericevent<string,string>); } public string delegatereturn<t,s>(t title,s author) { return title.tostring() + author; } private void genericevent<v, f>(v name, f address) { // }
在这里我们看到我在梆定delegatereturn的时候并没有带泛型参数。在这里的泛型参数其实是没什么意义的。因为他的类型取决于调用委托的方法的类型。也就是在前面那段代码中invokeevent方法的类型,这里的delegatereturn要用泛型方法是可以随时跟invokeevent的参数类型保持一至。这样梆定后我们再来调用gd.getvalues("my generic post","fastyou");这样调用的其实就是delegatereturn的方法,这就是委托的好处了,同样调用gd.invokeevent("my generic post","fastyou");就是genericevent方法。
委托 可以定义自己的类型参数。引用泛型委托的代码可以指定类型参数以创建已关闭的构造类型,就像实例化泛型类或调用泛型方法一样,如下例所示:
public delegate void del<t>(t item); public static void notify(int i) { } del<int> m1 = new del<int>(notify);
c# 2.0 版具有称为方法组转换的新功能,此功能适用于具体委托类型和泛型委托类型,并使您可以使用如下简化的语法写入上一行:
del<int> m2 = notify;
在泛型类内部定义的委托使用泛型类类型参数的方式可以与类方法所使用的方式相同。
class stack<t> { t[] items; int index; public delegate void stackdelegate(t[] items); }
引用委托的代码必须指定包含类的类型变量,如下所示:
private static void dowork(float[] items) { } public static void teststack() { stack<float> s = new stack<float>(); stack<float>.stackdelegate d = dowork; }
根据典型设计模式定义事件时,泛型委托尤其有用,因为发送方参数可以为强类型,不再需要强制转换成 object,或反向强制转换。
delegate void stackeventhandler<t, u>(t sender, u eventargs); class stack<t> { public class stackeventargs : system.eventargs { } public event stackeventhandler<stack<t>, stackeventargs> stackevent; protected virtual void onstackchanged(stackeventargs a) { stackevent(this, a); } } class sampleclass { public void handlestackchange<t>(stack<t> stack, stack<t>.stackeventargs args) { } } public static void test() { stack<double> s = new stack<double>(); sampleclass o = new sampleclass(); s.stackevent += o.handlestackchange; }
上一篇: C#简单输出日历的方法
下一篇: C#创建不规则窗体的4种方式详解