天天看点

C# 4.0 New Feature

  1. Covariance and Contravariance

在 .NET Framework 4 中,Func 泛型委托(如 Func<T, TResult>)具有协变返回类型和逆变参数类型。Action 泛型委托(如 Action<T1, T2>)具有逆变参数类型。这意味着,可以将委托指派给具有派生程度较高的参数类型和(对于 Func 泛型委托)派生程度较低的返回类型的变量。

(in 关键字)输入参数为逆变,(out 关键字)返回值为协变。

public interface IEnumerable<out T> { /* ... */ }      

Notice the out keyword modifying the definition of the type parameter, T. When the compiler sees this, it will mark T as covariant and check that, in the definition of the interface, all uses of T are up to snuff (in other words, that they’re used in out positions only—that’s why this keyword was picked).

总结:

You can add the keyword in or out whenever you define a type parameter, and doing so gives you free extra conversions.

1.First, this works with generic interfaces and delegates only. You can’t declare a generic type parameter on a class or struct in this manner.

2.Second, whenever you have an interface or delegate with a covariant or contravariant type parameter, you’re granted new conversions on that type only when the type arguments, in the usage of the interface (not its definition), are reference types.

2.Dynamic Dispatch

C# 4.0 New Feature

有了 dynamic 关键字,就不需要按照这种方式使用反射来调用某个对象的 MyMethod 方法,而是可以告诉编译器:请将 o 视为动态的,将所有分析都推迟到运行时。

dynamic o = GetObject();

int i = o.MyMethod();

在 C# 4.0 中,dynamic 是一种内置类型,用一个伪关键字标出。但是请注意,这种 dynamic 与 var 不同。用 var 声明的变量实际上具有强类型,不过程序员将其留给编译器判断罢了。当程序员使用 dynamic 时,编译器不知道要使用的类型,程序员将这种判断留给运行时决定。

Within the type system of a programming language, covariance and contravariance refers to the ordering of types from narrower to wider and their interchangeability or equivalence in certain situations (such as parameters, generics, and return types).

  • covariant: converting from narrower (float) to wider (double).协变,派生类->基类
  • contravariant: converting from wider (double) to narrower (float).逆变,基类->派生类
  • invariant: Not able to convert (Null).

 3.Named Arguments and Optional Parameters

在 C# 的另一项新增功能中,方法现在支持具有默认值的可选参数.

class Car {

  public void Accelerate(

    double speed, int? gear = null,

    bool inReverse = false) {

  }

}

Car myCar = new Car();

myCar.Accelerate(55);

这种方式与以下代码等效:

myCar.Accelerate(55, null, false);

由于编译器将插入您省略的所有默认值,因此这两段代码完全相同。

通过前缀的方式,可以改变参数的顺序进行调用。      
e.Accelerate(gear:5,inReverse:true,speed:20.0);      

 4.C# 4.0 在 COM 互操作类型上支持带索引的属性

Application excel = new Application();      
5.在 COM 调用点省略 Ref 关键字      
6.嵌入 COM 互操作类型
这更像是 C# 编译器功能,而不像是 C# 语言功能,但您现在可以使用 COM 互操作程序集,而不要求该程序集在运行时必须存在。      
目的是减轻将 COM 互操作程序集与您的应用程序一起部署的负担。
       
7.并行编程      
1)Parallel vs. Concurrent:      
并发(Concurrent):Concurrency is about executing multiple un-related tasks (无关任务) in a concurrent mode.       
What these un-related tasks share are system resources(共享相同的系统资源), but they do not share a common problem to solve;       
meaning, they are logically independent(这些任务逻辑上独立).      
并行(Parallel):Parallelism is taking a certain task and dividing it into a set of related tasks (相关任务)to be executed concurrently.      
2)Parallel Context:the .NET Thread Pool.      
The thread pool is exposed through the          System.Threading.ThreadPool                 namespace, and it has been available since before .NET v 4.0      
3)Task      
  • 创建Task task1 = Task.Factory.StartNew;      
  • var second= task1.ContinueWith():表示在task1执行完之后再执行task2.(这两个task分别运行在不同的Thread)      
Console.WriteLine(second.Result);主线程将等待secdond执行完之后,才开始输出second.Result.(Cool)      

4)PLINQ/Extention:类似LINQ,使用AsParallel()来进行并行查询,加快查询速度;

int[] results = arr.AsParallel().Select ( (x) => x+5); 

foreach (var x in results)
    {
        Console.WriteLine(x);
    }      
如果把计算结果(可能分配到不同的线程计算)打印出来,可能会随机的。      
C# 4.0 New Feature
如果要确保调用的顺序输出结果,则使用AsOrdered extension forces the use of a buffer where all work units' outputs are gathered and arranged       
before being flushed back to the final output.,如图:      
C# 4.0 New Feature
5).Parallel:使用Task.Parallel.For()      
System.Threading.Tasks.Parallel.For(0, 10, i =>
    {
        counter++; //这里可能不是你想要的结果,并发引起的。      
加锁/同步解决:      
Interlocked.Increment(ref counter);      
}      

继续阅读