· 泛型可以代表一切数据类型,包括值类型、引用类型 由于声明泛型时代表范围太广 牵扯到装拆箱,又或者在某些情况下,确定类型方向时 可以使用泛型的约束。将声明的泛型类型限制在某一特点下,声明泛型时提出约束,调用或实例化泛型时再遵守约束可缩小泛型的数据类型范围。
格式:在声明泛型的方法名或类名后添加关键字:where 泛型字符 :+ 约束条件
约束条件-值类型(Struct):
将泛型类型限制在值类型,只能传入基本数据类型、自定义结构体等。
namespace ConsoleApp4
{
internal class Program
{
static void Main(string[] args)
{
Func<MyStruct1>(new MyStruct1());
}
static void Func<T>(T t) where T : struct
{
Console.WriteLine(t.GetType());//输出 ConsoleApp4.MyStruct1
}
}
public struct MyStruct1
{
}
}
约束条件-引用类型(Class):
将泛型类型限制在引用类型类型,只能传入类型为类的泛型类型。
namespace ConsoleApp4
{
internal class Program
{
static void Main(string[] args)
{
MyClass<string> myClass1 = new ConsoleApp4.MyClass<string>("kkk");
}
}
public class MyClass<T> where T : class
{
public T _valT;
public MyClass(T t)
{
Console.WriteLine($"{t.GetType()}");
_valT = t;
}
}
}
约束条件-指定类型:
明确泛型为某一类时,可以直接使用该类型进行限制。限制传入类型为约束类型或约束类型的继承者。
namespace ConsoleApp4
{
internal class Program
{
static void Main(string[] args)
{
Func1(new MyClassBase());//输出 : ConsoleApp4.MyClassBase
Func1(new MyClass1());//输出 : ConsoleApp4.MyClass1
Func1(new MyClass2());//输出 : ConsoleApp4.MyClass2
}
static void Func1<T>(T obj) where T : MyClassBase
{
Console.WriteLine(obj.GetType());
}
}
public class MyClassBase { }
public class MyClass1 : MyClassBase{ }
public class MyClass2 : MyClassBase { }
}
约束条件-公开无参构造(new ()):
公开无参构造即约束该泛型必须拥有无参实例化的功能,非抽象类。
namespace ConsoleApp4
{
internal class Program
{
static void Main(string[] args)
{
// Func1<MyClassBase>(new MyClassBase(10));//报错
Func1<MyClass1>(new MyClass1());
Func1<MyStruct1>(new MyStruct1());
}
static void Func1<T>(T t) where T : new()
{
}
}
public struct MyStruct1 { }//结构体 永远有一个公开无参构造函数 并不可手写
public class MyClass1 { }//实例类 没有构造函数时 有提供一个公开无参构造函数可手写
}
多泛型时约束:
namespace ConsoleApp4
{
interface ISpeek { }
internal class Program
{
static void Main(string[] args)
{
Func1<MyClass1, MyClass2>(new MyClass1(),new MyClass2());
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"> 约束T 为引用类型</typeparam>
/// <typeparam name="C"> 约束C 为继承了ISpeek 接口的类型</typeparam>
/// <param name="t"></param>
/// <param name="c"></param>
static void Func1<T,C>(T t,C c) where T : class where C : ISpeek
{
}
}
public class MyClass1 { }
public class MyClass2:ISpeek { }
}