C# 5.0将带来的五大新特性(大收录)

来源:互联网 发布:高碳钢做刀怎么样知乎 编辑:程序博客网 时间:2024/06/01 10:05

(Visual Studio 2012 .net framework 4.5)

C# 5.0 抢先看

 

第一:绑定运算符,:=:

这个只是简化了数据绑定,跟ASP.NET MVC3不断改进一样,其实不是什么亮点改进。

 

comboBox1.Text :=: textBox1.Text; //将文本框的内容绑定到下拉框。

 

第二:带参数的泛型构造函数:

这个的加入给一些设计增加了强大功能,泛型早在C#2.0加入后就有着强大的应用,一般稍微设计比较好的框架,都会用到泛型,C#5.0加入带参数泛型构造函数,则在原有基础上对C#泛型完善了很多。:)

 

public class T MyClass : T: classnew()

//we might have 

 
public class T MyClass : T:classnew(int)

 

第三:支持null类型运算:

此功能,个人觉得并非什么大的亮点,但至少对null类型,特别是有数据计算的这种null类型的支持,写代码还是方便不少。

注意对于Nullable Types,在C#2.0就加入进来了,但是不支持计算,比如:

int? x null;
int? y + 40;

那么y值是多少?不支持计算,得到的是null,想必大家知道为什么结果是null了吧?但C#5.0可以,40加一个null的整数,我们要的结果是40,不过份吧?

 

int x? = null;

int y? = x + 40;

 

 

Myobject obj = null;

Myotherobj obj2 
= obj.MyProperty ??? new Myotherobj();

 

第四:case支持表达式:

这个是一个我很早就想如果能这样就好了,没想到在C#5.0里就加入此功能,以前case里只能写一个具体的常量,而现在可以加表达式了,灵活多了。 

复制代码
switch(myobj){

 
case string.IsNullorEmpty(myotherobj):

 //逻辑代码 

  
case myotherobj.Trim().Lower: 

 //逻辑代码
}

 
复制代码

 

第五:扩展属性。

我们在C#3.0里有扩展方法,那么在C#5.0里将会加入扩展属性的感念,对照扩展方法,不难理解扩展属性的概念了。以下为扩展属性的定义举例:

[Associate(string)]
public static int Zivsoft_ExtensionProperty { get;set;}

 

 

C#5.0 远远不只是上面描述的5点新功能,它如同C#4.0加入dynamic概念一样,会加入异步处理概念,这个不是几行代码就能表达,而是将在设计,架构上,又会掀起一次飞跃……

为了大家抢先看,就给一段C#5.0一段简单的异步操作的代码例子,注意(C#5.0两个新加的关键字asyncawait):

复制代码
Task<Movie> GetMovieAsync(string title);
Task PlayMovieAsync(Movie movie);
async 
void GetAndPlayMoviesAsync(string[] titles)
{
    
foreach (var title in titles)
    {
        var movie 
= await GetMovieAsync(title);
        await PlayMovieAsync(movie);
    }
}
复制代码

 

我不知道都有多少人关心C# 5.0?随便搜了一下,好像博客园里面没啥这方面的信息。

目前能看到的最详细的资料就是异步编程的资料了,这里贡献一下视频资料:(Anders Hejlsberg主讲的,推荐阅读一下。)

http://player.microsoftpdc.com/Session/1b127a7d-300e-4385-af8e-ac747fee677a

Jeffrey Zhao翻译过这个视频,英文听力不好的,可以看他的翻译:

http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-1.html 

如果你嫌这个说的不够清楚,还可以看看C#开发团队的博客:

http://msdn.microsoft.com/hi-in/vcsharp/aa336719

其中谈到异步开发的是这个:

http://blogs.msdn.com/b/ericlippert/ 

 

另外一个比较清楚的是Compiler as a Service,所谓的清楚是指“清楚知道有这方面的内容”,但是至于演示或者示例代码,那就很少了。如果谁有具体的Url,可以回复给我,我给在这里面添上。

 

但是还有什么呢?似乎就没了。目前网上所说的很多都是各自的WishList,博客园里面也有人转了别人的WishList。这些WishList我不太感兴趣,因为就算想得再好,最后也就是YY一下,没啥意义。所以,如果你知道有哪些Url在说C# 5.0的新内容,包括新语法,新功能,预计推出时间等,不妨贡献出来,大家好提前了解一下,哪怕是小道消息也行。(只要不是WishList就好。)

 

话锋一转,我真的要赞扬一下,那个async/await实在是太给力了,完全超越了我的想象。我敢肯定这个绝对是C# 5.0里面影响范围最广的东西,比PLinq还要广。因为界面响应速度其实是一件很重要的事情,这对MacOS/iPhone的成功还是做出了不小的贡献的。SilverLight里面非常注重这一点,很多地方会限定你必须用异步方式实现,例如WCF调用就是。现在我们实现起来就比较累,而且看着还比较丑。如果有async/await,那就实在太给力了。

 

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,
            [CallerMemberNamestring memberName = "",
            [CallerFilePathstring sourceFilePath = "",
            [CallerLineNumberint 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。


0 0
原创粉丝点击