读书笔记: C# 7.0 in a nutshell (第 四 章 Advanced C#- 上)

这篇博客详细介绍了C# 7.0中的高级特性,包括委托(Delegate)的用法,如多播委托、泛型委托和Func/Action,事件(Events)的工作原理及标准事件模式,Lambda表达式的多种形式和闭包概念,以及异常处理(Try和Exception)。还探讨了枚举和迭代器,可空类型,扩展方法和匿名类的相关知识。
摘要由CSDN通过智能技术生成

内容:

第四章(上): Advanced C#

  1. Delegate
  2. Events
  3. Lamda
  4. Anonymous Methods
  5. Exception Handler
  6. Enumeration & Iterartor
  7. Nullable Types
  8. Extension Methods
  9. Anonymous Types

1. Delegate

一个delegate type定义了 delegate 实例可以调用的方法类型。

例子:

// 这里定义了一个delegate类型,规定输入输出的参数类型
delegate int Transformer (int x);

class Test
{
    static void Main()
    {
        //Transformer t = new Transformer (Square);
        Transformer t = Square; // Create delegate instance
        //t.Invoke(3)
        int result = t(3); // Invoke delegate
        Console.WriteLine (result); // 9
    }

    static int Square (int x) => x * x;
}

1.1 Writing Plug-in Methods with Delegates

就是把委托当做函数的参数, 这个函数就叫做高阶函数: high-order function

1.2 Multicast Delegates☆

每个delegate instance可以引用不止一个target method:

SomeDelegate d = SomeMethod1;
d += SomeMethod2;

注意

  1. 调用delegate instance的顺序,会和 添加引用顺序一致;
  2. delegate 是不可变的,当使用 +=-=的时候,实际上是创建了一个新的delegate instance,再给他赋值
  3. 如果被代理的method有返回值,那么调用delegate得到的返回值为最后执行的method的返回值
  4. 所有delegate继承自System.MulticastDelegate,再继承自System.Delegate
  5. 使用+=-=实际上会被编译成System.Delegate的静态方法:CombineRemove

1.3 实例目标方法 vs. 静态目标方法

当一个delegate instance 引用了某个实例 target method的时, System.Delegate类的Target属性维护了这个方法的实例对象, Method属性指向了这个方法。

class Test
{
    static void Main()
    {
        X x = new X();
        ProgressReporter p = x.InstanceProgress;
        p(99); // 99
        Console.WriteLine (p.Target == x); // True
        Console.WriteLine (p.Method); // Void InstanceProgress(Int32)
    }
}
class X
{
public void InstanceProgress (int percentComplete)  => Console.WriteLine (percentComplete);
}

1.4 泛型委托

定义委托类型的时候可以使用泛型

public delegate T Transformer<T> (T arg);

1.5 Func & Action

除了 ref/outpointer 参数的 delegate,其他基本都可以用这两个替换

1.6 Delegate vs. Interface

用delegate解决的地方也能使用接口解决,那么何时使用delegate更好:

  1. 接口本身只定义了一个方法
  2. 需要multicast delegate
  3. subscriber需要多次实现接口

1.7 Delegate兼容性

a. 类型兼容性

delegate类型都彼此不兼容,就算他们 函数签名相同:

delegate void D1();
delegate void D2();
...
D1 d1 = Method1;
D2 d2 = d1; // Compile-time error
// 但是下面这个可以
D2 d2 = new D2 (d1);

Delegate相等的条件是,他们的target methods相等:

D d1 = Method1;
D d2 = Method1;
Console.WriteLine (d1 == d2); // True

Multicast delegates are considered equal if they reference the same methods in the same order.

b. 参数兼容性

delegate的参数具有 contravariance: (比如 传object参数的方法 给 string参数的delegate)

static void ActOnObject (object o) => Console.WriteLine (o); 
...
delegate void StringAction (string s);
StringAction sa = new StringAction (ActOnObject);

c. 返回值兼容性:

delegate的参数具有 covariance: (比如 传string返回值的方法 给 object返回值的delegate)

static string RetrieveString() => "hello";
...
delegate object ObjectRetriever();
ObjectRetriever o = new ObjectRetriever (RetrieveString);
d. 泛型delegate使用variance

如果定义泛型的delegate,好的习惯是:

  1. 把作为返回值的type parameter表示为 out
  2. 把作为参数传入的 type parameter 表示为 int

2. Events

目的:

     使用delegate主要是为了实现broadcaster-subscriber模式。 broadcaster内有一个 delegate instance, subscriber通过向这个delegate instance注册target method,来接收消息;broadcaster来决定何时invoke这个delegate。

Events作用:

event是C#提供的实现这个模式的语法, 它相当于是 delegate的一个子集,只提供了完成 subscriber模式必须的功能。event的存在是为了阻止 subscriber间的相互干扰。

// Delegate definition
public delegate void PriceChangedHandler (decimal oldPrice,
decimal newPrice);
public class Broadcaster
{
    // Event declaration
    public event PriceChangedHandler PriceChanged;
}

在上面的 Broadcaster类中,可以像对待delegate一样对待这个event; 而在这个类的外面,只能使用+=-=

好处☆:

虽然没有event,代码也同样执行,但是event能提供如下的安全性:

  1. 让其他的subscriber没有办法重新赋值 PricedChanged,而只能使用 +=
  2. 没法让event清除所有的subscriber
  3. 没办法从外部调用event

2.1 Event内部怎么工作的

public class Broadcaster
{
    public event PriceChangedHandler PriceChanged;
}

compiler会把上面的,转换成类似下面这样:

PriceChangedHandler priceChanged; // private delegate
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值