泛型方法
在方法上使用类型参数。
泛型方法 是 CoddyKit 上的免费 C# Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。
什么是泛型方法?
泛型方法会声明一个或多个属于自身的类型参数,这些参数写在方法名称后的尖括号中。这样,同一个方法体就能适用于多种类型,无需进行转换或重复编写。
类型参数是类似 T 的占位符。编译器会在调用位置替换为实际类型,同时保持完整的类型安全。
void Print<T>(T value)
{
Console.WriteLine(value);
}声明类型参数
类型参数列表 <T> 位于方法名称和参数列表之间。在方法体内部,您可以将 T 用作参数类型、返回类型或局部变量类型。
按照惯例,单个类型参数通常命名为 T;TKey 等描述性名称也很常见。
T Echo<T>(T input)
{
return input;
}使用类型推断调用
通常不需要显式指定类型参数。编译器会根据您传入的参数推断出 T。
这里,Echo(42) 会推断出 T = int,而 Echo("hi") 会推断出 T = string。类型推断让泛型调用保持简洁易读。
using System;
class Program
{
static T Echo<T>(T input) => input;
static void Main()
{
Console.WriteLine(Echo(42));
Console.WriteLine(Echo("hi"));
}
}显式类型参数
当推断无法确定类型,或者您希望明确指定类型时,请在调用位置的尖括号中提供类型参数。
当没有任何参数携带该类型信息时,这是必需的。例如,某个方法的 T 只出现在返回类型中。
T Create<T>() where T : new() => new T();
// call:
var list = Create<int>();多个类型参数
泛型方法可以声明多个类型参数,并用逗号分隔。每个参数都会独立进行推断或显式提供。
一个经典示例是交换两个值,或构建一个包含两种不同类型的配对对象。
(TSecond, TFirst) Flip<TFirst, TSecond>(TFirst a, TSecond b)
{
return (b, a);
}泛型交换
对于不依赖具体类型的实用工具,泛型方法非常适合。交换操作可以重新排列任意匹配类型的两个值。
ref 关键字允许方法直接修改调用方的变量。
using System;
class Program
{
static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
static void Main()
{
int x = 1, y = 2;
Swap(ref x, ref y);
Console.WriteLine($"{x} {y}");
}
}方法参数的约束
泛型方法可以使用 where 子句限制其类型参数。约束会告诉编译器可以对 T 执行哪些操作。
下面的 where T : IComparable<T> 使方法体能够安全地调用 CompareTo。
T Max<T>(T a, T b) where T : IComparable<T>
{
return a.CompareTo(b) >= 0 ? a : b;
}非泛型类中的泛型方法
类不必是泛型类,也可以包含泛型方法。静态实用工具类通常会集中存放这类方法。
这样可以将通用辅助功能归在一起,而不必让整个类都携带类型参数。
static class Util
{
public static T First<T>(T[] items) => items[0];
}从数组进行推断
类型推断同样适用于数组和集合参数。传入 int[] 会自动推断出 T = int。
这让泛型算法使用起来就像语言内置功能一样自然。
using System;
class Program
{
static T First<T>(T[] items) => items[0];
static void Main()
{
int[] nums = { 10, 20, 30 };
Console.WriteLine(First(nums));
}
}为什么不直接使用 object?
在泛型出现之前,代码会使用 object 和类型转换。这会丢失类型安全性,并对值类型进行装箱,从而影响性能。
泛型方法可以避免值类型装箱,并在编译时发现类型错误,而不是等到运行时抛出错误。
// Unsafe: needs a cast and can fail at runtime
object Echo(object o) => o;
int n = (int)Echo(5);返回不同类型
返回类型本身也可以是泛型的,从而让一个方法根据调用方确定其输出类型。default(T) 对值类型返回零值,对引用类型返回 null。
当没有可用值时,这对于提供安全的回退值很有帮助。
T OrDefault<T>(bool ok, T value)
{
return ok ? value : default(T);
}快速检查
测试您对泛型方法的理解。
总结
泛型方法会在名称后的尖括号中声明自己的类型参数。编译器通常会根据参数推断类型,但您也可以显式提供类型。
泛型方法能够保持类型安全、避免装箱,并支持 where 约束。它们可以放在任何类中,无论该类是否为泛型类。
用 AI 导师学习 C# — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 93
- 课程
- 346
常见问题解答
「泛型方法」课时是免费的吗?
是的 — 「泛型方法」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。
「泛型方法」这节课中我会学到什么?
在方法上使用类型参数。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C# Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「泛型方法」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C# Academy 课中编写并运行代码吗?
能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。