这个系列没有先后顺序,主要是为了加深自己的理解,通过这样记录自己也会在过程中去产生跟多的思考。从零开始的学习,就借这个自己记录一下,结合的书籍是《C#图解教程(第四版)》和自己的脑洞理解,不那么靠谱还请见谅~
泛型
C#提供了六种自定义的类型(class、struct、array、enum、delegate、interface),通过这六种类型我们已经可以去建立很复杂具体的对象。有时我们会为了一个用途去写某个模块(记作MyStruct),但事后发现该模块其实还可以用在别的地方,但是由于处理的数据不同这时候可能映入脑中的是,大不了在写一个模块,改变一下数据类型。这个方法确实能解决这个问题,但如果太多的情况下要使用这个模块这种简单的方法无疑是增加了代码的耦合。
而泛型便可以很好的解决这个问题,C#提供了五种泛型(类、结构、接口、委托和方法)
下面则是一个类泛型的例子
class MyStruct {
const int lenght = 10;
private int[] arry;
private int index = 0;
public void Push(int i) {
if (arry == null)
arry = new int[lenght];
arry[index] = i;
index++;
}
public int Peek()
{
return arry[index-1];
}
}
class MyStruct<T>
{
const int lenght = 10;
private T[] arry;
private int index = 0;
public void Push(T i)
{
if (arry == null)
arry = new T[lenght];
arry[index] = i;
index++;
}
public T Peek()
{
return arry[index - 1];
}
}
class Program
{
static void Main(string[] args)
{
int a = 12;
int b = 10;
string m = "Hello";
MyStruct myStruct1 = new MyStruct();
MyStruct<string> myStruct2 = new MyStruct<string>();
myStruct1.Push(a);
myStruct1.Push(b);
myStruct2.Push(m);
Console.WriteLine(myStruct1.Peek());
Console.WriteLine(myStruct2.Peek());
}
}
通过泛型,可以非常方便去重用一些模块。T在这里是一个占位符,也可以用其他来代替。
泛型类的声明如下:
-在类名之后放置一组尖括号。
-在尖括号中用逗号分隔的占位符字符串来表示希望提供的类型。这叫做类型参数(typeparameter)。
-在泛型类声明的主体中使用类型参数来表示应该替代的类型。
class SomeClass<T1, T2>where T1:System.Type
where T2:System.Object
//T1,T2 为类型参数
{
public T1 SomeValue = T1;
public T2 SomeObject = new T2();
}
上面是泛型类的一种抽象实现。,这里出现了where,它是泛型中的约束。
约束
对于第一个我们定义的泛型栈来说,它对所有类型参数都只是做了Push和Peek的操作,并没用到项本身的运算符的事情。但在我们的实际情况下,我们不得不去访问处理一些类型的对象,这时,如果不去约束的话往往编译时会报错。
要让泛型变得更有用,我们需要提供额外的信息让编译器知道参数可以接受哪些类型。这些额外的信息叫做约束。
约束使用where子句列出。
-每一个约束有约束的类型参数有自己的where字句
-如果形参有多个约束,它们在where字句中使用逗号分隔。
where TypeParam : constraint , constraint, ...
class MyClass<T1,T2,T3> where T2 : Customer
where T3 : IComparable
{
....
}
网友评论