this & <T>)皮皮(Pipi)最近写代码时,遇到了两个让他非常抓狂的问题。
每次把文本变成数字,他都要写:
int hp = int.Parse("100");皮皮抱怨:
“为什么不能像说话一样顺畅,直接写
"100".ToInt()? 微软为什么不在string类里加上这个方法?”
游戏里需要经常“随机抽卡”: 抽怪物、抽装备、抽掉落物……
皮皮抓狂:
“我给
List<Monster>写了一个随机抽取方法, 又要给List<Item>写一个几乎一模一样的! 这太蠢了!”
瓜瓜(Guagua)扶了扶墨镜:
“既然原厂不给力,我们就自己造! 今天教你把 扩展方法 (
this) 和 泛型魔法 (<T>) 结合起来,打造终极外挂!”

系统核心类(比如 string)是“密封”的(sealed), 你连源码都打不开,更别提修改了。
但 扩展方法 允许你在不修改源码的情况下, 给它挂载一个“外接插件”。
static class(静态类)里staticthis 关键字string 加上 ToInt()publicstaticclassStringExtensions{publicstaticintToInt(thisstring str) {if (int.TryParse(str, outint result)) {return result; }return0; }}调用效果:
string myHp = "999";int hp = myHp.ToInt();this + <T>)在我们之前的第 09 期文章里,我们已经讲过泛型集合:
👉 《C# 学习笔记 09:无限背包与魔法图鉴 —— 集合 (List & Dictionary)”》
还记得吗?List<T> 就是一个“万能背包”。
现在,我们要在这个万能背包上——
装外挂。
List<T> 加上随机抽取能力publicstaticclassListExtensions{publicstatic T GetRandom<T>(this List<T> list) {if (list == null || list.Count == 0)returndefault; Random rand = new Random();int randomIndex = rand.Next(list.Count);return list[randomIndex]; }}List<string> names = new List<string> { "皮皮", "瓜瓜", "史莱姆" };List<int> numbers = new List<int> { 10, 50, 100 };string luckyName = names.GetRandom();int luckyDamage = numbers.GetRandom();Console.WriteLine($"天选之子是:{luckyName},伤害 {luckyDamage}!");自动类型推断生效。一套逻辑,通杀所有类型。
当你写:
myHp.ToInt();编译器会翻译成:
StringExtensions.ToInt(myHp);扩展方法并没有修改原类。
它只是:
让代码看起来像“原生自带”。
还记得第 10 期我们学的:
Where()Select()OrderBy()数组本身并没有这些方法。
微软写了一个巨大静态类:
Enumerable里面塞满了 泛型扩展方法:
publicstatic IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate)这就是:
this<T>组合爆发的威力。
this | ||
<T> | ||
this + <T> |
皮皮遇到了一个哲学问题:
int itemId = 0;但 0 也是合法物品 ID。
如何真正表示“空”?
下一期,我们探索: