泛型类
泛型类定义
public class Student<T>
{
}
其中T可以是任何类型,T可以是任意字母字符,但需要C#的命名规则,T能有多个类型参数 ,多个用逗号连接就可以啦
public class Student<T, T2>
{
}
注意:
1 定义了T后 可以将T作为 变量的类型 属性和方法的返回类型 以及参数类型
public partial class Student<T>
{
public T MyProperty { get; set; } //T变量类型
public T MyVoid() //T 方法的返回类型
{
return default(T);//返回T类型的默认值
}
public T MyPropertys { get { return MyPropertys; } }//属性的返回类型
public void Findperson(T t1,T t2) { }
}
2 需要注意定义的T不能假定为某种类型 (示例为前面代码的追加)
public partial class Student<T>
{
public T MyProperty { get; set; } //T变量类型
public T MyVoid() //T 方法的返回类型
{
return default(T);//返回T类型的默认值
}
public T MyPropertys { get { return MyPropertys; } }//属性的返回类型
public void Findperson(T t1,T t2)
{
t1 = new Myclass();
}
}
public class Myclass
{
}
约束泛型
1 在前面的泛型类,定义当中。类型T 、当前的T是未写任何约束,所以它可以是任何类型。在程序当中我们有时是需要对我们想要的数据类型范围进行指定,避免出现非必要得异常。
public class Student<T> where T:Constraint
{
}
示例解释:
用 where 关机键来实现 T是指定为T得约束+冒号+约束类型 其中得Constraint 是一个类 我们不需要知道这类实现了什么功能,内含什么代码。只需要当前得约束时指定为T数据类型必须是继承当前类或者是当前类得基类。
2 多个数据类型,和多个数据约束
public class Student<T,T2> where T : Constraint
where T2:class//使用多个where 指定所有类型上得约束
{
}
public class Student2<T4, T5,T6> where T4 : new()
where T5 : class,ICommand,INotifyPropertyChanged
where T6 : T5
{
}
示例解释:
上述示例代码当中有T,T2数据类型 其中T 的约束和前面的示例解释一样,T2的数据约束是指定了当前的约束必须是引用类型。
下面的Student2类当中的T4的数据约束是指定了当前的类型必须包含一个公共的无参的构造函数。T5的约束是指定了当前的约束不仅是引用类型,而且必须实现了Icommand以及INotifyPropertyChanged接口。T6的约束则是和T5的约束一致 被称之为裸类型约束(naked type Constraint)
补充:如果类需要继承也需要写约束的情况下 约束必须出现在继承的后面
public class Myclass
{
}
public class Student2<T4, T5,T6>:Myclass where T4 : new()
where T5 : class,ICommand,INotifyPropertyChanged
where T6 : T5
{
}
附录
从泛型类中继承
1 如果某类型所继承的基类中受到了约束 那么改类型就无法解除约束 ,它会继承当前基类中的约束,但我们可以进行约束的范围当中在次缩小范围,但不能违反基类的约束
public class Student5<T> where T : class
{
}
public class Student3<T>:Student5<T> where T:class
{
}
public class Student6<T> : Student5<T> where T : Constraint
{
}
示例解释:
上述代码当中Student5中的T类型的约束为引用类型,其中Student3继承Student5 其中Student3 中的T的约束便是继承了Student5当中的T约束 那么必须指定当前Student3当中的T数据约束类型,否在编译器会报错。
Student6和Student3一样都是继承Seudnet5但其中的Student6当中对T的约束进行了在基类的约束范围内更加缩小范围的指定,但需要知道必须是在基类的约束范围类 如 where T:struct 那么编译器便会报错,原因是一个是值类型一个是引用类型的约束。
2 这适用于继承了泛型类型的非泛型类
//正确示例
public class student10 : List<Myclass>, ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
throw new NotImplementedException();
}
public void Execute(object parameter)
{
}
}
//错误示例 未指定其中的T的信息
public class Student11 : List<T>,ICommand
{
}
示例解释:
上述代码当中Student10是继承了list泛型类 其中泛型类型指定为Myclass 并实现接口Icommand第二段代码是错误示例,编译器不会通过编译,提示未指定当前T类型信息。其中本章编译器是VS 2022