当前位置: 首页 > news >正文

C# 5.0中新增特性

C# 5.0随着VisualStudio 2012一起正式发布了,让我们来看看C#5.0中增加了哪些功能。

1. 异步编程

在.Net 4.5中,通过asyncawait两个关键字,引入了一种新的基于任务的异步编程模型(TAP)。在这种方式下,可以通过类似同步方式编写异步代码,极大简化了异步编程模型。如下式一个简单的实例:

    static async void DownloadStringAsync2(Uri uri)
    {
        var webClient = new WebClient();
        var result = await webClient.DownloadStringTaskAsync(uri);
        Console.WriteLine(result);
    }

而之前的方式是这样的:

    static void DownloadStringAsync(Uri uri)
    {
        var webClient = new WebClient();
        webClient.DownloadStringCompleted += (s, e) =>
            {
                Console.WriteLine(e.Result);
            };
        webClient.DownloadStringAsync(uri);
    }

也许前面这个例子不足以体现asyncawait带来的优越性,下面这个例子就明显多了:

    public void CopyToAsyncTheHardWay(Stream source, Stream destination)
    {
        byte[] buffer = new byte[0x1000];
        Action<IAsyncResult> readWriteLoop = null;
        readWriteLoop = iar =>
        {
            for (bool isRead = (iar == null); ; isRead = !isRead)
            {
                switch (isRead)
                {
                    case true:
                        iar = source.BeginRead(buffer, 0, buffer.Length,
                            readResult =>
                            {
                                if (readResult.CompletedSynchronously) return;
                                readWriteLoop(readResult);
                            }, null);
                        if (!iar.CompletedSynchronously) return;
                        break;
                    case false:
                        int numRead = source.EndRead(iar);
                        if (numRead == 0)
                        {
                            return;
                        }
                        iar = destination.BeginWrite(buffer, 0, numRead,
                            writeResult =>
                            {
                                if (writeResult.CompletedSynchronously) return;
                                destination.EndWrite(writeResult);
                                readWriteLoop(null);
                            }, null);
                        if (!iar.CompletedSynchronously) return;
                        destination.EndWrite(iar);
                        break;
                }
            }
        };
        readWriteLoop(null);
    }

    public async Task CopyToAsync(Stream source, Stream destination)
    {
        byte[] buffer = new byte[0x1000];
        int numRead;
        while ((numRead = await source.ReadAsync(buffer, 0, buffer.Length)) != 0)
        {
            await destination.WriteAsync(buffer, 0, numRead);
        }
    }

关于基于任务的异步编程模型需要介绍的地方还比较多,不是一两句能说完的,有空的话后面再专门写篇文章来详细介绍下。另外也可参看微软的官方网站:Visual Studio Asynchronous Programming,其官方文档Task-Based Asynchronous Pattern Overview介绍的非常详细, VisualStudio中自带的CSharp Language Specification中也有一些说明。

2. 调用方信息

很多时候,我们需要在运行过程中记录一些调测的日志信息,如下所示:

    public void DoProcessing()
    {
        TraceMessage("Something happened.");
    }

为了调测方便,除了事件信息外,我们往往还需要知道发生该事件的代码位置以及调用栈信息。在C++中,我们可以通过定义一个宏,然后再宏中通过__FILE__和__LINE__来获取当前代码的位置,但C#并不支持宏,往往只能通过StackTrace来实现这一功能,但StackTrace却有不是很靠谱,常常获取不了我们所要的结果。

针对这个问题,在.Net 4.5中引入了三个Attribute:CallerMemberNameCallerFilePathCallerLineNumber。在编译器的配合下,分别可以获取到调用函数(准确讲应该是成员)名称,调用文件及调用行号。上面的TraceMessage函数可以实现如下:

    public void TraceMessage(string message,
            [CallerMemberName] string memberName = "",
            [CallerFilePath] string sourceFilePath = "",
            [CallerLineNumber] int sourceLineNumber = 0)
    {
        Trace.WriteLine("message: " + message);
        Trace.WriteLine("member name: " + memberName);
        Trace.WriteLine("source file path: " + sourceFilePath);
        Trace.WriteLine("source line number: " + sourceLineNumber);
    }

另外,在构造函数,析构函数、属性等特殊的地方调用CallerMemberName属性所标记的函数时,获取的值有所不同,其取值如下表所示:

调用的地方

CallerMemberName获取的结果

方法、属性或事件

方法,属性或事件的名称

构造函数

字符串 ".ctor"

静态构造函数

字符串 ".cctor"

析构函数

该字符串 "Finalize"

用户定义的运算符或转换

生成的名称成员,例如, "op_Addition"。

特性构造函数

特性所应用的成员的名称

例如,对于在属性中调用CallerMemberName所标记的函数即可获取属性名称,通过这种方式可以简化 INotifyPropertyChanged 接口的实现。关于调用方信息更详细的资料,请参看MSDN:http://msdn.microsoft.com/zh-cn/library/hh534540.aspx。

相关文章:

  • nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞
  • android 介绍
  • 前端性能--指标分析
  • 参加2012 OpenStack亚太技术大会
  • LVS笔记,(一)
  • Table doesn't have a primary key
  • linux 免密登录常见问题
  • JAVA数据结构的个人见解之绪论
  • UIScrollView 加载多个view view还可以交换顺序(2)
  • 迷宫最短路径(DFS)
  • SegmentFault for Android 3.0 发布
  • C++ 重写重载重定义区别
  • Python 网页爬虫 文本处理 科学计算 机器学习 数据挖掘兵器谱
  • 修改SQL Server序列号
  • 【数据结构】线性表之链表--C++语言描述
  • 【EOS】Cleos基础
  • 【笔记】你不知道的JS读书笔记——Promise
  • 【技术性】Search知识
  • C# 免费离线人脸识别 2.0 Demo
  • ComponentOne 2017 V2版本正式发布
  • Computed property XXX was assigned to but it has no setter
  • eclipse(luna)创建web工程
  • ES6核心特性
  • Flannel解读
  • Iterator 和 for...of 循环
  • javascript面向对象之创建对象
  • js ES6 求数组的交集,并集,还有差集
  • JS笔记四:作用域、变量(函数)提升
  • MySQL-事务管理(基础)
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • Python 反序列化安全问题(二)
  • win10下安装mysql5.7
  • windows下mongoDB的环境配置
  • 闭包--闭包作用之保存(一)
  • 缓存与缓冲
  • 基于组件的设计工作流与界面抽象
  • 前端
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 白色的风信子
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • #HarmonyOS:Web组件的使用
  • #pragma预处理命令
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (4)Elastix图像配准:3D图像
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (蓝桥杯每日一题)love
  • (力扣题库)跳跃游戏II(c++)
  • (一)SpringBoot3---尚硅谷总结
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)scrum常见工具列表
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一