可空类型:值类型可以为空。使用方式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可限制T2与T1相同,或继承自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;