深入解析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;
}
(0)

相关推荐

  • C#基础之泛型委托实例教程

    本文实例讲述了C#中泛型委托的用法,并以示例形式较为详细的进行了用法分析.分享给大家供大家参考之用.具体如下: 首先,泛型委托是委托的一种特殊形式,虽然感觉看上去比较怪异,其实在使用的时候跟委托差不多,不过泛型委托更具有类型通用性. 就拿C#里最常见的委托EventHandler打比方.在.NET 2.0以前,也就是泛型出现以前,普通的事件处理函数都由EventHandler定义,如下: public delegate void EventHandler(object sender, Event

  • C#泛型委托的用法实例分析

    本文实例讲述了C#泛型委托的用法.分享给大家供大家参考.具体分析如下: 冒泡排序大家都知道,例如一个整形数组,可以用冒泡排序来使它按从小到大的顺序排序, 但它仅限于了按整形数组来排序,如何做到按任意类型进行排序呢,例如按一个类的某个属性进行排序? 举例说明:定义一组以类MEmployee为元素的数组,按MEmployee的Salary属性进行排序,类似的可以引伸为对其他类型的比较 元素类定义: public class MEmployee { public string Name { get;

  • C#中Predicate<T>与Func<T, bool>泛型委托的用法实例

    本文以实例形式分析了C#中Predicate<T>与Func<T, bool>泛型委托的用法,分享给大家供大家参考之用.具体如下: 先来看看下面的例子: static void Main(string[] args) { List<string> l = new List<string>(); l.Add("a"); l.Add("b"); l.Add("s"); l.Add("t&quo

  • c#中的泛型委托详解

    今天学习一下c#中的泛型委托. 1.一般的委托,delegate,可以又传入参数(<=32),声明的方法为  public delegate void SomethingDelegate(int a); using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace delegateSummary { publ

  • 深入解析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&

  • 深入解析C++编程中基类与基类的继承的相关知识

    基类 继承过程将创建一个新的派生类,它由基类的成员加上派生类添加的任何新成员组成.在多重继承中,可以构建一个继承关系图,其中相同的基类是多个派生类的一部分.下图显示了此类关系图. 单个基类的多个实例 在该图中,显示了 CollectibleString 和 CollectibleSortable 的组件的图形化表示形式.但是,基类 Collectible 位于通过 CollectibleSortableString 路径和 CollectibleString 路径的 CollectibleSor

  • 深入解析Java编程中方法的参数传递

    在阅读本文之前,根据自己的经验和理解,大家可以先思考并选择一下Java函数的参数传递方式: A. 是按值传递的? B. 按引用传递的? C. 部分按值部分按引用? 此处暂不宣布正确答案,我们通过一个简单的例子让大家自己找答案: 1. 先定义一个类型Value public static class Value { private String value = "value"; public String getValue() { return value; } public void

  • 解析Python编程中的包结构

    假设你想设计一个模块集(也就是一个"包")来统一处理声音文件和声音数据.通常由它们的扩展有不同的声音格式,例如:WAV,AIFF,AU),所以你可能需要创建和维护一个不断增长的各种文件格式之间的转换的模块集合.并且可能要执行声音数据处理(如混合,添加回声,应用平衡功能),所以你写一个永无止境的流模块来执行这些操作:模块设计的包如下: sound/ Top-level package __init__.py Initialize the sound package formats/ Su

  • 深入解析Swift编程中的构造方法

    一.引言 构造方法是一个类创建对象最先也是必须调用的方法,在Objective-C中,开发者更习惯称这类方法为初始化方法.在Objective-C中的初始化方法与普通函数相比除了要以init抬头外并无太严格的分界,而在Swift语言体系中,构造方法与普通的方法分界十分严格,从格式写法上就有不同,普通方法函数要以func声明,构造方法统一为init命名,不需要func关键字声明,不同的构造方法采用方法重载的方式创建. 二.构造方法的复写与重载 在Objective-C中,不同的初始化方法就是不同的

  • 深入解析golang编程中函数的用法

    函数是一组一起执行任务的语句.每Go程序具有至少一个函数,它一般是main(),以及所有的最琐碎程序可以定义附加函数. 你可以将代码放到独立的功能.如何划分代码之间的不同功能,但逻辑上的划分通常是让每个函数执行特定的任务. 函数声明告诉编译器有关的函数的名称,返回类型和参数.一个函数定义提供了函数的实际主体. Go语言标准库提供了大量的内置函数,在程序可以调用.例如,函数len()需要不同类型的参数和返回值的类型的长度.例如,如果一个字符串传递给它,它会返回字符串的长度以字节为单位,如果一个数组

  • 深入解析C++编程中的静态成员函数

    C++静态成员函数 与数据成员类似,成员函数也可以定义为静态的,在类中声明函数的前面加static就成了静态成员函数.如 static int volume( ); 和静态数据成员一样,静态成员函数是类的一部分,而不是对象的一部分. 如果要在类外调用公用的静态成员函数,要用类名和域运算符"::".如 Box::volume( ); 实际上也允许通过对象名调用静态成员函数,如 a.volume( ); 但这并不意味着此函数是属于对象a的,而只是用a的类型而已. 与静态数据成员不同,静态成

  • 解析C++编程中的#include和条件编译

    文件包含的作用 所谓"文件包含"处理是指一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中.C++提供了#include命令用来实现"文件包含"的操作.如在file1.cpp中有以下#include命令: #include ″file2.cpp″ 它的作用见图示意. "文件包含"命令是很有用的,它可以节省程序设计人员的重复劳动. #include命令的应用很广泛,绝大多数C++程序中都包括#include命令.现在,

  • 深入解析JavaScript编程中的this关键字使用

    JavaScript 里的 this 到底指得是什么?很多人都会告诉你 this 指的是当前对象.这样理解对么?在大多数情况下确实没错.比如我们经常会在网页上写这样的 JavaScript: <input type="submit" value="提交" onclick="this.value='正在提交数据'" /> 这里的this显然指的是当前对象,即这个提交按钮.通常,我们使用this的情况都与此类似.但是有什么情况不是这样的呢

  • 深入解析Python编程中JSON模块的使用

    JSON编码支持的基本数据类型为 None , bool , int , float 和 str , 以及包含这些类型数据的lists,tuples和dictionaries. 对于dictionaries,keys需要是字符串类型(字典中任何非字符串类型的key在编码时会先转换为字符串). 为了遵循JSON规范,你应该只编码Python的lists和dictionaries. 而且,在web应用程序中,顶层对象被编码为一个字典是一个标准做法. JSON编码的格式对于Python语法而已几乎是完

随机推荐