C#(106):泛型 System.Collections.Generic及泛型继承、运算符、结构、接口、方法、委托、事件、可空类型等


一、定义泛型类

$1```
        {

            this.innerT1Object = item;

        }
    
```csharp
$1```

    }

注意:

```csharp
$1```
**2、可以把T看作继承System.Object的类型:typeof(T),T.ToString()**
```csharp
$1```

```csharp
    class MyGenericClass where T:Animal
        //…

    }

    if (op1 == op2)//错误,因为这就假定了T支持==运算符

    {

        //…

    }

}
$1```

    
    
```csharp
$1```
  4. 一个类型参数用作另一个类型参数的约束,表示T2与T1的类型相同,或T2继承于T1(裸类型约束)class Myclass where T2: T1
```csharp
$1```

```csharp
$1```
    }
```csharp
$1```
    }
```csharp
$1```
    {
```csharp
$1```

    
    
```csharp
$1```

```csharp
$1```
        bool Brea(T animal1, T animal2);

        T oldest { get; }
```csharp
    public delegate T1 MyDelegate(T2 op1, T2 op2) where T1 : T2;
public interface IComparable
$1```
    public class Person : IComparable
```csharp
$1```
    
```csharp
$1```

        {

```csharp
$1```
### 2、泛型类
```csharp
$1```

```csharp
$1```
        public void Process(T1 op1)//重载方法1
```csharp
    public delegate void EventHandler(object sender, TEventArgs e) where TEventArgs : EventArgs;
$1```
    
    
    Action action1 = () => Console.Write("a");

    action1();
```csharp
$1```
    public T Find(Predicate matach);

举例:
```csharp
$1```

```csharp
$1```
    string[] _value = { "charlies", "nancy", "alex", "jimmy", "selina" };
```csharp
$1```
    public void Sort(Comparision comprison)
```csharp
$1```
    
    public delegate TSummary Action(TInput t, TSummary u);//定义泛型委托

    public static TSummary Accumulate(IEnumerable  cols, Action action)

    //将委托实例action传给方法参数。

    {

        TSummary sum = default(TSummary);

        foreach (TInput input in cols)

        {

            sum = action(input, sum);//执行委托方法

        }

        return sum;

    }

    

    void Main()

    {

        decimal amount = Accumulate(new List { 1, 2 }, (a, b) => a + b);//(a, b) => a + b为委托实例

        Console.Write(amount);

    }

## 八、定义泛型事件

事件与委托就像一对孪生兄弟。既然有泛型委托,那么也应该有泛型事件。因为在以前,事件处理函数的发送方参数的类型总是Object。因此事件处理函数没有办法根据不同的发送者身份或者类型对事件进行不同的处理。现在如果使用泛型事件就可以使用强类型的发送方,不再需要强制转换成Object或反向强制转换。而且也可以根据发送方类型的不同对消息进行不同的处理。

例子中演示了发送方是强类型的情况,在这个例子中使用泛型类Publisher来表示消息的发布者,用类Receiver来表示消息的订阅者。
```csharp
    //定义了一个泛型委托,该委托指定了发送者的具体类型

    public delegate void MyEventHandler(Publisher Sender);

    

    void Main()

    {

        //事件发布者

        Publisher publisherI = new Publisher();

        Publisher publisherD = new Publisher();

    

        //事件订阅者

        Receiver receiver = new Receiver();

    

        //开始绑定事件

        publisherI.Click += receiver.OnClick;

        publisherD.Click += receiver.OnClick;

    

        //引发事件

        publisherI.SendMessage();

        publisherD.SendMessage();

    }

    

    //消息发布者类Publisher的代码

    public class Publisher

    {

        //定义了一个泛型事件,该事件的发布者的类型是强类型

        public event MyEventHandler Click;

    

        //发送事件函数

        public void SendMessage()

        {

            Click(this);

        }

    }

    

    //消息订阅者类Receiver的代码

    class Receiver

    {

        //事件处理函数,该函数具有强类型的参数表示发送者

        public void OnClick(Publisher sender)

        {

            Console.WriteLine("该事件已经写入日志文件");

        }

    

        //事件处理函数

        public void OnClick(Publisher sender)

        {

            Console.WriteLine("该事件已经发送到主管信箱");

        }

    }

九、可空类型System.Nullable

1、声明和赋值

    Nullable x = 4;//可写成int? x = 4

    x = null;//可为可空类型赋值null.

2、判断为空

    int y;

    if (x.HasValue)//或者x!=null

    {

        y = x = value;

    }

    else

    {

        y = x ?? 0;//或者    x.GetValueOrDefault(); x=null则或者其默认值。

    }

3、转换

    int? op1=5;

    int? result=op1 *2;

    

    int? op2=5;

    int result1=op2 *2;//如果op2为null,强制转换int?到int产生异常

十、ArraySegement 数组片段

    int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 };

    ArraySegment segment = new ArraySegment(arr, 2, 3);

    for (int i = segment.Offset; i < segment.Offset + segment.Count; i++)

    {

        Console.WriteLine(segment.Array[i]);

    }

相关