《深入理解C#》—— 类型约束和类型推断(第三章)

显而易见 类型约束的目的就是为了约束入参的参数类型

一共有四种约束可供使用,分别是引用类型约束,值类型约束,构造函数类型约束,转换类型约束

1、引用类型约束

确保类型实参是引用类型,表示成 T : Class,且必须是类型参数指定的第一个约束(可能会有多个约束)。类型实参任何类、接口、数组、委托、或者已知识引用类型的另一个类型实参:

//约束类
public class TypeConstraintDemo
{
	/// <summary>
	/// 引用类型约束实例
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <param name="entity"></param>
	public void SaveStudentInfo<T>(T entity) where T : class
	{
		//TODO 逻辑
	}
}

//引用类型约束实例
TypeConstraintDemo typeConstraintDemo = new TypeConstraintDemo();
Student stu = new Student();
stu.id = 1;
stu.name = "Jack";
stu.age = 13;
typeConstraintDemo.SaveStudentInfo<Student>(stu);

2、值类型约束

表示成 T : struct,确保类型实参是值类型,不包括可空类型

/// <summary>
/// 值类型约束实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
public Student GetStudentById<T>(T entity) where T : struct
{
	//TODO 逻辑
	return new Student();
}

//值类型约束调用
typeConstraintDemo.GetStudentById<int>(1);

3、构造函数类型约束

表示成 T : new(),必须是所有类型参数的最后一个参数,它检查类型实参是否有一个可用于创建类型参数的无参构造函数

适用于以下三种情况:

1)所有值类型

2)所有没有显式声明构造函数的非静态、非抽象类

3)所有显式声明了一个公共午餐构造函数的非抽象类

public T CreateInstance<T>() where T :  new()
{
    return new T();
}


//报错,因为string 没有一个无参的构造方法
typeConstraintDemo.CreateInstance<string>();
//正确
typeConstraintDemo.CreateInstance<Student>();
//正确
typeConstraintDemo.CreateInstance<int>();

4、转换类型约束

允许指定另一个类型,类型实参必须可以通过一致性、引用或者装箱转换隐式地转换为该类型。

还可以规定一个类型实参必须可以转换为另一个类型实参

实例

声明例子
class Sample<T> Where T : Stream

有效: Sample<Stream> (自一致性转换)

无效:Sample<string>

struct Sample <T> where T : IDisposable

有效:Sample<SqlConnection>(引用转换)

无效:Sample<StringBuilder>

class Sample<T> where T :IComparable<T>

有效:Sample<int> (装箱转换)

无效:Sample<FileInfo> 

class Sample<T,U> where T :U

有效:Sample<Stream,IDisposable>(引用转换)

无效:Sample<string,IDisposable>

可以指定多个接口,但是只能指定一个类

class Sample<T> where T : Stream,IEnumerable<string>,IComparable<int>

指定的类不可以是结构、密封类或者System.Object、System.Enum、System.ValueType和System.Delegate中任意一个。

5、组合约束

将不同种类的约束合并到一起。

不同类型参数可以有不同的约束,它们分别由一个单独的where引入

下面是一些无效的组合约束及其解释

//不可以同时是引用类型和值类型
class Sample<T> where T : class, struct
//不可以同时是值类型和引用类型
class Sample<T> where T : struct, class
//Stream没有无参的构造函数且new()必须是最后一个约束
class Sample<T> where T : new(), Stream
//IDisposable在Stream后面
class Sample<T> where T : IDisposable, Stream
//不可以同时添加两个一样的约束
class Sample<T> where T : xmlReader, IComparable, IComparable
//U不可以同时是引用类型约束和值类型约束
class Sample<T> where T : struct where U : class, T
//每个约束都必须使用单独的wehere ,U 应该有单独的where
class Sample<T> where T : Stream, U : IDisposable

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值