C#五大泛型约束
C#六大泛型约束基类约束接口约束new()构造函数约束引用/值类型约束组合约束基类约束基类约束有两个功能,首先,它允许泛型类使用基类约束所定义的的成员,第二个功能是确保泛型类使用指定基类的类型实参,这意味着,在使用泛型类时,类型实参必须是基类本身或者是派生自该基类的类。class Program{static void Main(string[] args)...
C#五大泛型约束
基类约束
基类约束有两个功能,首先,它允许泛型类使用基类约束所定义的的成员,第二个功能是确保泛型类使用指定基类的类型实参,这意味着,在使用泛型类时,类型实参必须是基类本身或者是派生自该基类的类。
class Program
{
static void Main(string[] args)
{
StudentList<Pupil> pupillist = new StudentList<Pupil>();
StudentList<StudentBase> studentList = new StudentList<StudentBase>();
pupillist.Add(new Pupil() { Name = "Bob", Age = 10, Chinese = 99, English = 99, Math = 99, Gender = Gender.Male });
pupillist.Add(new Pupil() { Name = "Alice", Age = 10, Chinese = 100, English = 100, Math = 80, Gender = Gender.Female });
}
}
enum Gender
{
Male,
Female
}
//学生基类
class StudentBase
{
public int Age { get; set; }
public string Name { get; set; }
public Gender Gender { get; set; }
}
//派生自学生基类的小学生类
class Pupil:StudentBase
{
public int Chinese { get; set; }
public int Math { get; set; }
public int English { get; set; }
}
class StudentList<T> where T : StudentBase
{
List<T> Studentlist = new List<T>();
public void Add(T t)
{
Studentlist.Add(t);
}
public void Delete(T t)
{
Studentlist.Remove(t);
}
}
上述代码定义了一个“学生基类”,其中包含三个属性:年龄,姓名,性别。毕竟只要你是学生, 你肯定有这三种最基本的属性。然后定义了一个小学生类,小学生肯定属于学生,所以继承了“学生基类”,除此之外,他们要学习语文数学英语三门科目,因此定义了这三项属性。
然后定义了一个学生列表泛型类,他有泛型基类约束where T : StudentBase
,这个约束有两层含义,一层含义是说,在我定义的这个学生列表泛型类之中,我可以使用StudentBase这个“学生基类”所定义的成员,另一层含义是指,当我使用这个学生列表泛型类去创建对象的时候,<> 方括号里面必须是学生基类StudentBase本身或者是派生自学生基类StudentBase的其他类,前面所提到的类型实参 ,按个人理解,应该就是指方括号里面的东西。在这个例子里面,方括号可以填两种类型,一种是StudentBase
,另一种是Pupil
,填其他任何类型或者不填都会报错。
接口约束
接口约束是指定某个类型实参必须实现的接口。他的两个功能其实和基类约束一样,一个是允许在泛型类中使用接口的成员,另一个是要求类型实参必须是接口本身或者是实现接口的类,下面一个很简单的例子用来说明:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Compare<int>.CompareTo(1, 2));//输出:2
Console.WriteLine(Compare<string>.CompareTo("a", "b"));//输出:b
}
}
//接口约束
public class Compare<T> where T:IComparable
{
public static T CompareTo(T t1,T t2)
{
if (t1.CompareTo(t2) > 0)
{
return t1;
}
else
{
return t2;
}
}
}
new()构造函数约束
new()构造函数约束允许开发人员实例化一个泛型类型的对象。new()约束要求类型实参必须提供一个无参数的公有构造函数。使用new()约束时,可以通过调用该无参数的构造函数来创建对象。new()构造函数约束的形式为:
where T:new ()
使用new()约束时应当注意3点:
- new()约束可以与其他约束一起使用,但必须位于约束列表的末端
- new()约束仅允许开发人员使用无参数的构造函数构造一个对象,即使同时存在其他的构造函数也是如此。即不允许给类型形参的构造函数传递实参。
- 不可以同时使用new()约束和值类型约束。因为值类型和new()都隐式的提供了一个无参公共构造函数。
class Pupil : StudentBase
{
public Pupil(int id)
{
}
public Pupil()
{
}
public int Chinese { get; set; }
public int Math { get; set; }
public int English { get; set; }
}
给前述例子中的StudentList泛型类添加new()约束以后,在上述代码中,如果没有public Pupil() {}
这个无参构造函数而仅仅有public Pupil(int id) { }
这个含参构造函数的话,代码编译报错,提示:“Pupil”必须是具有公共的无参数构造函数的非抽象类型,才能用作泛型类型或方法“StudentList”中的参数“T” ,而且,如果要在泛型类实例化变量类型“T”,则同样需要new()约束,否则会编译报错。
引用/值类型约束
引用/值类型约束将一般类型参数约束为引用类型或值类型。
struct 约束将一般类型参数约束为值类型(例如,int、bool 和 enum);
class 约束将一般类型参数约束为引用类型(类)
组合约束
以上各种泛型约束可以进行组合,形成组合约束。组合约束要按一定顺序才能符合要求,它的第一项必须是引用/值类型约束或基类约束,接下来是接口约束,最后是new()约束。
更多推荐
所有评论(0)