C#—泛型

来源:互联网 发布:河南省进出口数据 编辑:程序博客网 时间:2024/05/16 15:27

可空类型:值类型可以为空。使用方式System.Nullable<T> name; T为int、double等。如System.Nullable<int> val;缩写形式为int? val;

       可空类型可以拥有值null,如val = null;可以使用HasValue属性和Value属性,若HasValue属性为true,则Value属性有一个非空值;若HasValue是false,则变量被赋予了null。

       int? op = 5;

       int? result1 = op * 2;

       int result2 = (int)op * 2; 或int result2 = op.Value * 2;

       空接合运算符??是二元运算符,如果第一个操作数不是null,该运算符就等于第一个操作数,否则就等于第二个操作数。如intresult = op * 2 ?? 5;

List<T>泛型集合类型,其中类型是T,创建T类型对象的集合List<T> myCol = new List<T> ();

       可以使用的方法和属性:Count;Add(T item);Clear();Contains(T item);Remove(T item);RemoveAt(int index);IndexOf(T item)等。可以进行类似于数组的访问T item = myCol[2];

       对泛型列表排序(Sort)可以使用泛型委托Comparison<T>,其返回类型和参数是int method(T objectA, T objectB);搜索(FindAll等)可以使用泛型委托Predicate<T>,其返回类型和参数是bool method(T object)。

键值对集合Dictionay<K, V>

       Dictionary<string, int> things = new Dictionary<string, int> ();

可以使用Keys和Values属性迭代集合中的键和值:

foreach(string key in things.Keys)

{

}

foreach(int val in things.Values)

{

}

还可以用KeyValuePair<K, V>来迭代集合中各项:

foreach(KeyValuePair(string, int) thing in things)

{

       Console.WriteLine(“{0} = {1}”, thing.Key, thing.Value);

}

定义泛型类型

class MyGenericClass<T1, T2>      //不能假定为类提供了什么类型

{

       private T1 object;

       public MyGenericClass(T1 item)

       {

              object = item;

       }

       ……

}

public MyGenericClass()

{

       object = default(T1);

}

关键字default:如果object是引用类型,就给它赋null值;如果它是值类型,就给它赋默认值(数字类型是0)。

通过约束类型可以限制可用于实例化泛型类的类型,约束必须出现在继承说明符后面:

class MyGenericClass<T> where T :constraint1, constraint2

{

       ……

}

还可以使用多个where语句:

class MyGenericClass<T1, T2> where T1 : constraint1 where T2 : constraint2

{

       ……

}

(constraint1、constraint2)可用的约束:struct,必须是值类型;class,必须是引用类型;任意类名,必须是基类或继承自基类;interface,必须是接口或实现了接口;new(),必须有一个公共的无参构造函数。如果new()作约束,必须为类型指定的最后一个约束。

可以把一个类型参数用作另一个类型参数的约束:class MyGenericClass<T1, T2> where T1 : T2

两个继承自Animal类的类Cow和类Chicken,类SuperCow继承自类Cow

class Farm<T> where T : Animal则继承自该泛型类的类型必须受到至少与基类型相同的约束,也可以为其子集,如class SuperFarm<T> : Farm<T> where T : SuperCow

可以在泛型类中进行运算符的重写,如:

public static Farm<T> operator +(Farm<T> farm1, Farm<T> farm2)

{

       ……

}

public struct MyStruct<T1, T2>     //泛型结构

{

       public T1 item1;

       public T2 item2;

}

interface MyFarmInterface<T> where T : Animal      //泛型接口

{

       bool AttemptToBreed(T animal1, T animal2);

}

泛型方法

public T GetDefault<T> ()

{

       return default(T);

}

如果类是泛型的,就必须为泛型方法类型使用不同的标识符:

public class Defaulter<T1>

{

       public T2 GetDefault<T2> ()    //where T2 : T1可限制T2T1相同,或继承自T1

       {

              return default(T2);

       }

}

定义泛型委托,只需声明和使用一个或多个泛型类型参数:

public delegate T1 MyDelegate<T1, T2> (T1 op1, T2 op2);

协变:在类型定义中使用out关键字把泛型类型参数定义为协变。

public interface IMethaneProducer<out T>

{

       ……

}

假定Cow支持IMethaneProducer<Cow>接口,则

Cow myCow = new Cow();

IMethaneProducer<Cow> cowMethaneProducer = myCow;

协变能使下述代码成立:

IMethaneProducer<Animal> animalMethaneProducer = cowMethaneProducer;

抗变:在类型定义中使用in关键字把泛型类型参数定义为抗变。

public interface IGrassMuncher<in T>

{

       ……

}

假定Cow支持IGrassMuncher<Cow>接口,则

Cow myCow = newCow();

IGrassMuncher<Cow> cowGrassMuncher = myCow;

抗变能使下述代码成立:

IGrassMuncher<SuperCow> superCowGrassMuncher = cowGrassMuncher;
0 0
原创粉丝点击