C# 泛型简介 02

2019-08-19  本文已影响0人  JeetChan

声明

本文内容来自微软 MVP solenovex 的视频教程——真会C#? - 第3章 泛型简介(完结),大致和第 2 课—— 3.9 泛型约束、子类、自引用、静态数据、转换 对应。可在 GitHub 中查看 C# 视频教程的配套PPT

本文主要包括以下内容:

  1. 泛型的约束
  2. 泛型类型的子类
  3. 自引用的泛型声明
  4. 静态数据
  5. 类型参数和转换

泛型的约束

默认情况下,泛型的类型参数(parameter)可以是任何类型的。如果只允许使用特定的类型参数(argument),就可以指定约束。泛型的约束可以作用于类型或方法的定义。

where T : base-class // Base-class constraint
where T : interface // Interface constraint
where T : class // Reference-type constraint
where T : struct // Value-type constraint (excludes Nullable types)
where T : new() // Parameterless constructor constraint
where U : T // Naked type constraint

泛型类型的子类

泛型 class 可以有子类,在子类里,可以继续让父类的类型参数保持开放。

class Stack<T> {...}
class SpecialStack<T> : Stack<T> {...}

在子类里,也可以使用具体的类型来关闭(封闭)父类的类型参数。class IntStack : Stack<int> {...}子类型也可以引入新的类型参数。

class List<T> {...}
class KeyedList<T,TKey> : List<T> {...}

技术上来讲,所有子类的类型参数都是新鲜的。你可以认为子类先把父类的类型参数(argument)给关闭了,然后又打开了。为这个先关闭后打开的类型参数(argument)带来新的名称或含义。

class List<T> {...}
class KeyedList<TElement,TKey> : List<TElement> {...}

自引用的泛型声明

在封闭类型参数(argument)的时候,该类型可以把它自己作为具体的类型。

public interface IEquatable<T> { bool Equals (T obj); }
public class Balloon : IEquatable<Balloon>
{
    public string Color { get; set; }
    public int CC { get; set; }
    public bool Equals (Balloon b)
    {
        if (b == null) return false;
            return b.Color == Color && b.CC == CC;
    }
}

class Foo<T> where T : IComparable<T> { ... }
class Bar<T> where T : Bar<T> { ... }

静态数据

针对每一个封闭类型,静态数据是唯一的。

class Bob<T> { public static int Count; }

class Test
{
    static void Main()
    {
        Console.WriteLine (++Bob<int>.Count); // 1
        Console.WriteLine (++Bob<int>.Count); // 2
        Console.WriteLine (++Bob<string>.Count); // 1
        Console.WriteLine (++Bob<object>.Count); // 1
    }
}

类型参数和转换

C# 的转换操作符支持下列转换:

决定采用的是哪种转换,发生在编译时,根据已知类型的操作数来决定。

StringBuilder Foo<T> (T arg)
{
    if (arg is StringBuilder)
    return (StringBuilder) arg; // Will not compile
    ...
}

StringBuilder Foo<T> (T arg)
{
    StringBuilder sb = arg as StringBuilder;
    if (sb != null) return sb;
    ...
}

return (StringBuilder) (object) arg;

int Foo<T> (T x) => (int) x; // Compile-time error

int Foo<T> (T x) => (int) (object) x;
泛型

参考

Generics (C# Programming Guide)
Generic Methods (C# Programming Guide)
Generic Classes (C# Programming Guide)

上一篇 下一篇

猜你喜欢

热点阅读