限制
变性类型参数只能在接口和委托类型中声明,这是CLR的限制。变性只能应用在类型参数的按引用转换之间。例如,IEnumerable<int>不能作为IEnumerable<object>使用,因为从int到object的转换是装箱转换,而不是引用转换。
还要注意的是,CTP中并没有包含前面提到的.NET类型的新版本。为了试验变性,你需要自己声明变性接口和委托类型。
COM示例
这里有一个稍大一些的Office自动化示例,展示了大部分C#新特性的实际应用。
using System;
using System.Diagnostics;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;
class Program
{
static void Main(string[] args) {
var excel = new Excel.Application();
excel.Visible = true;
excel.Workbooks.Add(); // optional arguments omitted
excel.Cells[1, 1].Value = "Process Name"; // no casts; Value dynamically
excel.Cells[1, 2].Value = "Memory Usage"; // accessed
var processes = Process.GetProcesses()
.OrderByDescending(p => p.WorkingSet)
.Take(10);
int i = 2;
foreach (var p in processes) {
excel.Cells[i, 1].Value = p.ProcessName; // no casts
excel.Cells[i, 2].Value = p.WorkingSet; // no casts
i++;
}
Excel.Range range = excel.Cells[1, 1]; // no casts
Excel.Chart chart = excel.ActiveWorkbook.Charts.
Add(After: excel.ActiveSheet); // named and optional arguments
chart.ChartWizard(
Source: range.CurrentRegion,
Title: "Memory Usage in " + Environment.MachineName); //named+optional
chart.ChartStyle = 45;
chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
Excel.XlCopyPictureFormat.xlBitmap,
Excel.XlPictureAppearance.xlScreen);
var word = new Word.Application();
word.Visible = true;
word.Documents.Add(); // optional arguments
word.Selection.Paste();
}
}
using System.Diagnostics;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;
class Program
{
static void Main(string[] args) {
var excel = new Excel.Application();
excel.Visible = true;
excel.Workbooks.Add(); // optional arguments omitted
excel.Cells[1, 1].Value = "Process Name"; // no casts; Value dynamically
excel.Cells[1, 2].Value = "Memory Usage"; // accessed
var processes = Process.GetProcesses()
.OrderByDescending(p => p.WorkingSet)
.Take(10);
int i = 2;
foreach (var p in processes) {
excel.Cells[i, 1].Value = p.ProcessName; // no casts
excel.Cells[i, 2].Value = p.WorkingSet; // no casts
i++;
}
Excel.Range range = excel.Cells[1, 1]; // no casts
Excel.Chart chart = excel.ActiveWorkbook.Charts.
Add(After: excel.ActiveSheet); // named and optional arguments
chart.ChartWizard(
Source: range.CurrentRegion,
Title: "Memory Usage in " + Environment.MachineName); //named+optional
chart.ChartStyle = 45;
chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
Excel.XlCopyPictureFormat.xlBitmap,
Excel.XlPictureAppearance.xlScreen);
var word = new Word.Application();
word.Visible = true;
word.Documents.Add(); // optional arguments
word.Selection.Paste();
}
}
比起C# 3.0编写的等价代码,这段代码更加简洁可读。
尤其注意如何动态地访问Value属性的。这实际上是一个索引属性,也就是说,这是一个带有参数的属性;C#并不能理解这种属性。然而其参数是可选的。由于访问是动态进行的,运行时COM绑定器会知道用默认值替换参数并调用索引属性。因此,动态COM可以避免访问Excel区域的令人迷惑的Value2属性。
与Visual Basic的关系
C# 4.0中引入的大量特性已经或者将要以另外的形式引入Visual Basic中——
- VB中的迟绑定在很多方面都和C#中的动态查找很像,并且将来会更多地使用DLR,与C#更加等价。
- 命名参数和可选参数在Visual Basic中已经存在很久了,这个特性的C#版本明显会使与VB的互操作能力最大化。
- 无PIA和变性会同时引入VB和C#。
VB也增加了大量曾经是C#所独有的特性。C#和VB未来的版本在功能上将更加等价,这对于每个人都是有益的
资源
有关C# 4.0的所有可用的资源都可以在C# Dev Center找到(www.csharp.net)。该白皮书和其他资源可以在Code Gallery站点找到(code.msdn.com/csharpfuture)。祝愉快!