C# Academy · 课时

泛型方法

在方法上使用类型参数。

第 1 / 4 课13 个步骤

泛型方法 是 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 泛型方法
  2. 泛型类
  3. where 约束
  4. 泛型接口
← 返回 C# Academy