上一节介绍了泛型的声明和优点,下面着重介绍在类和方法中使用泛型。
一、泛型类
1、default
泛型可以作为方法的返回值,但是如果没有给泛型添加约束,则泛型可以是值类型或者是引用类型。那么方法的默认返回值就无法确定。而 default 关键字就可以用来解决这个问题。如 default(T),当T是值类型时,为默认值0,而当T是引用类型时,值是默认值 null。
下面给出泛型类的声明:
public class MyClass<T>
{
// T 作为方法的返回类型,没有约束
public T GetInfo()
{
// 根据调用时的实际请况返回对应的值
return default(T);
}
}
下面是调用的示例:
MyClass<int> a = new MyClass<int>();
int b = a.GetInfo();// b = 0
MyClass<string> c = new MyClass<string>();
string d = c.GetInfo();// d = null
注意:default 在switch 语句中表示默认情况,在泛型中根据值类型或引用类型给出默认值 0 或 null。
2、继承
泛型类和非泛型类都可以继承自泛型类。
注意:
(1)、泛型类继承自基类时,必须重复(基类有多个泛型时可以部分重复,未重复的泛型须要指定类型)基类的泛型或者是指定基类的类型。
(2)、非泛型类必须要指定基类泛型的类型。
下面给出示例:
public class BaseClass<T>
{
}
// 1、泛型类重复继承
public class SubClass<T>:BaseClass<T>
{
}
// 2、泛型类指定父类的类型
public class SubClass1<T>:BaseClass<int>
{
}
public class BaseClass1<T,T1>
{
}
// 3、泛型类部分重复继承,未重复的泛型必须要指定类型
public class SubClass2<T>:BaseClass1<T,int>
{
}
// 4、非泛型类继承自泛型类必须指定泛型的类型
public class SubClass3:BaseClass<int>
{
}
3、静态成员
虽然类的静态成员可以使用类名来访问,但是不同类型的泛型类的静态成员是不同的。
下面给出示例:
// 泛型类 StaticDemo 中有一个静态字段 a
public class StaticDemo<T>
{
public static int a;
}
调用时示例:
StaticDemo<int>.a = 4;
StaticDemo<string>.a = 5;
// 因为泛型类 StaticDemo 使用不同的类型,因此他们是两个静态字段。
int result = StaticDemo<int>.a;// result = 4
二、泛型方法
泛型方法的声明:在方法名之后,参数列表前,约束放在参数列表之后,方法体之前。
1、泛型方法的调用
当指定了参数的类型后,可以不用把泛型的类型赋予方法调用,编译器会自动获取参数的类型,可以像调用非泛型方法那样调用方法。
下面给出示例:
public static int Test<T>(T obj)
{
return 0;
}
// 参数是 int 类型 Test(1)== Test<int>(1)
int a = Test(1);
// 参数是 string 类型 Test("drt")== Test<string>("drt")
int b = Test("drt");
2、方法重载
重载:方法名相同,参数列表(参数类型或个数)不同的方法。
泛型方法可以像对于包括泛型方法的重载方法,在编译时会自动匹配(优先查找非泛型)最佳的方法。
下面给出示例:
public static int Test<T>(T obj)
{
return 0;
}
public static string Test(int obj)
{
return "";
}
// Test 有非泛型的重载方法,参数是 int 类型,编译时最先匹配该方法
string a = Test(1);
// 参数是 string ,没有非泛型的重载方法,匹配泛型方法
int b = Test("drt");