泛型学习.
泛类学习
一.应用场景
1.效率.
2.易用,容错.
3.处理同一类事情.
二.应用.
1.无论在声明变量还是实例变量都要指定使用那个变量代替<T>
2.内部算法和数据操作保持不变
三.使用.
1.编译器不知道使用将要指定的具体类型
2.派生约束.,以逗号分割多个约束.
为使用的一般类型参数分别指定约束.以空格分割.
基类约束(最多一个).
可以同时约束一个基类以及一个或多个接口,但是该基类必须首先出现在派生约束列表中

public class LinkedList where K : IComparable,IConvertible //多个约束以逗号分割
public class LinkedList where K : IComparable
where T : ICloneable
public class MyBaseClass
{...}
public class LinkedList where K : MyBaseClass
public class LinkedList where K : MyBaseClass, IComparable
3.构造函数约束
class Node where T : new()
{
public K Key;
public T Item;
public Node NextNode;
public Node()
{
Key = default(K);
Item = new T(); //构造函数使用.
NextNode = null;
}
}
public class LinkedList where K : IComparable
where T : ICloneable
public class MyBaseClass
{...}
public class LinkedList where K : MyBaseClass
public class LinkedList where K : MyBaseClass, IComparable
3.构造函数约束
class Node where T : new()
{
public K Key;
public T Item;
public Node NextNode;
public Node()
{
Key = default(K);
Item = new T(); //构造函数使用.
NextNode = null;
}
}
4.可以将构造函数约束与派生约束组合起来,前提是构造函数约束出现在约束列表中的最后:
public class LinkedList where K : IComparable,new()
5.引用/值类型约束
可以使用 struct 约束将一般类型参数约束为值类型(例如,int、bool 和 enum),或任何自定义结构:
public class MyClass where T : struct
{...}
//同样,可以使用 class 约束将一般类型参数约束为引用类型(类):
public class MyClass where T : class
{...}
{...}
//同样,可以使用 class 约束将一般类型参数约束为引用类型(类):
public class MyClass where T : class
{...}
6.编译器允许您将一般类型参数显式强制转换到其他任何接口,但不能将其转换到类:

interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass
{
void SomeMethod(T t)
{
ISomeInterface obj1 = (ISomeInterface)t;//Compiles
SomeClass obj2 = (SomeClass)t; //Does not compile
}
}
//7.代码块 6. 对一般类型参数使用“is”和“as”运算符
public class MyClass
{
public void SomeMethod(T t)
{
if(t is int)
{...}
if(t is LinkedList)
{...}
string str = t as string;
if(str != null)
{...}
LinkedList list = t as LinkedList;
if(list != null)
{...}
}
}
8.一般类型参数的转换.
泛型和强制类型转换
C# 编译器只允许将一般类型参数隐式强制转换到 Object 或约束指定的类型,如代码块 5 所示。这样的隐式强制类型转换是类型安全的,因为可以在编译时发现任何不兼容性。
代码块 5. 一般类型参数的隐式强制类型转换

interface ISomeInterface
{...}
class BaseClass
{...}
class MyClass where T : BaseClass,ISomeInterface
{
void SomeMethod(T t)
{
ISomeInterface obj1 = t;
BaseClass obj2 = t;
object obj3 = t;
}
}
//编译器允许您将一般类型参数显式强制转换到其他任何接口,但不能将其转换到类:
interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass
{
void SomeMethod(T t)
{
ISomeInterface obj1 = (ISomeInterface)t;//Compiles
SomeClass obj2 = (SomeClass)t; //Does not compile
}
}
9.从泛型类继承的类,要指明具体的参数.
public class BaseClass<T>
{...}
public class SubClass : BaseClass<int>
{...}
{...}
public class SubClass : BaseClass<int>
{...}
10.如果子类也是泛类,基类的约束需要在子类重新规范一边
public class BaseClass<T> where T : ISomeInterface
{...}
public class SubClass<T> : BaseClass<T> where T : ISomeInterface
{...}
{...}
public class SubClass<T> : BaseClass<T> where T : ISomeInterface
{...}
//2.1
public class BaseClass<T> where T : ISomeInterface
{...}
public class SubClass<T> : BaseClass<T> where T : ISomeInterface
{...}
public class BaseClass<T> where T : ISomeInterface
{...}
public class SubClass<T> : BaseClass<T> where T : ISomeInterface
{...}
11 如果基类有泛型虚方法,子类可以重载,但是必须指明具体类型.
public class BaseClass<T>
{
public virtual T SomeMethod()
{...}
}
public class SubClass: BaseClass<int>
{
public override int SomeMethod()
{...}
}
{
public virtual T SomeMethod()
{...}
}
public class SubClass: BaseClass<int>
{
public override int SomeMethod()
{...}
}
12 但是如果子类也是泛型,则重载时也可使用子类的<T>:
public class SubClass<T>: BaseClass<T>
{
public override T SomeMethod()
{...}
}
{
public override T SomeMethod()
{...}
}
13. 泛类的其它泛型参数以及约束.

public void Clone<T2>(T2 target)
where T2 : EBaseResItem<T2>
{
foreach (var property in AllProperties)
{
var pName = property.PropertyInfo.Name;
var p2 = EBaseResItem<T2>.AllProperties.FirstOrDefault(p => p.PropertyInfo.Name == pName);
if (p2 != null)
{
this.LoadProperty(property.PropertyInfo, target.ReadProperty(p2.PropertyInfo));
}
}
}
where T2 : EBaseResItem<T2>
{
foreach (var property in AllProperties)
{
var pName = property.PropertyInfo.Name;
var p2 = EBaseResItem<T2>.AllProperties.FirstOrDefault(p => p.PropertyInfo.Name == pName);
if (p2 != null)
{
this.LoadProperty(property.PropertyInfo, target.ReadProperty(p2.PropertyInfo));
}
}
}
14 可以定义泛型接口.
public interface ISomeInterface<T>
{
T SomeMethod(T t);
}
{
T SomeMethod(T t);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!