C#部分:
1.泛型的出现主要用于解决类、接口、委托、方法的通用性,通过定义泛型类、接口、委托、方法,可以让不同类型的数据使用相同运算规则处理数据,方便了开发。
2.利用System.Nullable<T>泛型可以生成可空的值类型变量,值类型的可空泛型可以简写为关键字加问号,如:int? val=new int?();
3.关于布尔类型的泛型可空& |操作,我们可以知道,如果关心不关心操作数是否为空就能得出结果,那么空值就是无所谓的。
4.可空的泛型值类型的HashValue属性值为true false,当该变量为空时,则HashValue为false。(HashValue和HashCode不是一回事,HashValue是泛型特有的)
5.可空泛型变量拥有特殊双目运算符:??,也叫做空接合运算符,val1??val2等价于 val1=val1==null?:val2;
6.泛型类有最基本的两类:List<T>和Dictionary<K,V>,(尖括号里表示类型的字母可以随便写)。前者表示顺序链表,后者表示键值和值的映射集合。当然我们也可以自己定义自己的泛型类,当然泛型类也会有禁忌:我们不能假定泛型T是哪种类型,所以也就不能进行针对的操作,这一切需要我们在声明泛型对象的时候才能揭晓。例如你不能用T类型重载+运算符。比如:
public class add<X> { public X op1; public Type returnValue() { return this.op1.GetType(); } } class test { public static void Main(String[] args) { add<string> a = new add<string>(); a.op1 = "10"; Console.WriteLine(a.returnValue()); Console.ReadKey(); } }
7.可以对泛型类的T进行约束,比如 public myTClass<T1,T2> where T1:class,interface,struct,基类名(访问性比T还要高的基类),new()(表示约束为有构造函数的公共基类函数,必须写在约束项的最后面)where T2:class,当然了,如果该泛型有继承的话,那么这些约束要写在继承后面:public myTClass<T>:IComparer<T> where T:class。
8.default关键字在泛型中用于确定T类型对象的初始化的值,如果T是值类型,那么初始化为0,如果T为引用类型,那么T对象初始化为null。例子如下:
public class add<X> { public X op1; public X returnValue() { X c=default(X); return c; } } class test { public static void Main(String[] args) { add<int> k = new add<int>(); Console.WriteLine(k.returnValue());//输出0 add<object> ks = new add<object>(); Console.WriteLine(ks.returnValue());//输出null Console.ReadKey(); } }
9.普通类如果继承泛型类,会出现错误,而如果继承的是约定好了类型的泛型类,比如 public class myClass:List<int> 则可以成立
10.泛型接口的应用于泛型类的继承,比如以下的例子:
public class com<T> :IComparer<T> { public int Compare(T x, T y) { int k = x.GetHashCode() - y.GetHashCode(); return k; } } class test { public static void Main(String[] args) { string[] arr = new string[] {"a","b","c" }; List<string> a = new List<string>(); a.AddRange(arr); com<string> k = new com<string>(); Console.WriteLine(k.Compare(a[0], a[1])); myDic.person.sayName(); Console.ReadKey(); } }
11.泛型委托的使用:
public delegate int myDelegate<T,X>(T x,X y); class test { public static void Main(String[] args) { test t1 = new test(); myDelegate<int,string> del = t1.add; Console.WriteLine(del(t1.add(2,"2"),t1.addString(4,"4"))); Console.ReadKey(); } public int add(int x, string y) { return x + y.GetHashCode(); } public string addString(int x, string y) { return x.ToString() + y; } }
12.泛型的运算符重载,需要注意:不能用泛型未知类作为重载返回类型,而且双目运算符之间的操作,参数也不能是类型相同的泛型类,总之感觉实现很复杂。但是肯定运算符是可以重载的。
13.泛型类的占位符可以和该泛型类中定义的泛型方法的占位符相同,但是最好不要这样。否则一旦你的泛型类实例化时和你的泛型方法实例化时的类型不一致或者无法做出隐式类型转换时,就会出现错误。