个人资料

跳过导航链接首页 > 博客列表 > 博客正文

C#基础学习,从事件说到泛型委托

:


系列目录:

0.从delegete委托开始说起

1.委托和事件绑定

2.泛型委托

3.委托和多线程

4.委托和async/await异步等待



泛型委托在事件的应用有很多.首先先说说按照泛型的要求,委托的写法本应该是这样的:

泛型委托,有返回值

public delegate T1 Mydelegate<T1,T2>(T2 x);

泛型委托,无返回值的

public delegate void Mydelegate<T1>(T1 x);

写法很别扭,好在.net下面针对泛型委托准备了两个现成的委托直接使用,.他们就是Action<>泛型委托和Func<>泛型委托.不要小看这两个泛型委托,他们有多达10个以上的泛型重载,能满足绝大多数的需要.使用Func有返回值的泛型委托,泛型列表中,返回值放在最后面

使用方式就简单得多了,如下:


public sealed partial class MyPage1 : Page
{
    //public delegate T1 Mydelegate<T1,T2>(T2 x);
    //public delegate void Mydelegate<T1>(T1 x);
    Action<string, int> DelAction;
    Func<double,double, double> DelFunc;
    public MyPage1()
    {
        this.InitializeComponent();
        DelAction = new Action<string, int>(dm1);
        DelFunc = new Func<double, double, double>(dm2);
    }
    public void dm1(string para1,int para2)
    {
    }
    public double dm2(double para1, double para2)
    {
        return para1 + para2;
    }
}


泛型委托在事件的应用有很多.在.NET系统内部同样定义了现成的委托EventHandler用于定义事件.例如下面是一个UWP中常用的选择文件对话框的后台代码.其中就是用了EventHandler 这样的泛型委托.


public sealed partial class LoaclFileControl : UserControl
{
    public StorageFile SelectedFile { get; set; }
    public event EventHandler<StorageFile> OnFileItemClicked;
    public LoaclFileControl()
    {
        this.InitializeComponent();
        //加载本地资源文件夹
        LoadFileList();
    }
 
    private async Task LoadFileList()
    {
        IReadOnlyList<StorageFile> StorageFiles = await FilesHelpper.GetLocalFilesAsync();
        FileGridView.DataContext = StorageFiles;
    }
 
    private void FileGridView_ItemClick(object sender, ItemClickEventArgs e)
    {
        if (e.ClickedItem is StorageFile file)
        {
            SelectedFile = file;
            OnFileItemClicked(this,SelectedFile);
        }
    }
}


观察上面的代码,可以看到OnFileItemClicked(this,SelectedFile);调用了事件(委托),对于EventHandler委托,参数为(sender,e.parameter).我们把参数传递进去,绑定方法的时候就可获得storageFile对象了.

public static async Task<string> RtfFile2HtmlAsync(StorageFile file) 
        { 
            string rtf=""; 
            switch (file.FileType) 
            { 
                case ".rtf": 
                    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 
                    using (Stream Fstream = await file.OpenStreamForReadAsync()) 
                    { 
                        using (StreamReader reader = new StreamReader(Fstream, Encoding.GetEncoding(0))) 
                        { 
                            rtf = reader.ReadToEnd(); 
                             
                        } 
                    } 
                    break; 
                default: 
                    break; 
            } 
            Task<string> result = new Task<string>( 
                () => { 
                    var html = Rtf.ToHtml(rtf); 
                    return html; 
                }); 
            result.Start(); 
 
            return await result; 
        } 


委托的事件就先写到这,使用委托作为参数传递方法也不写了,之后继续多线程吧.写委托离不开多线程.就用Task带进多线程/异步/等待的话题吧.上面的代码就用到了一点呢.


songshizhao
最初发表2018/6/13 23:26:09 最近更新2018/6/13 23:26:09 3437
为此篇作品打分
10