爱上C#的理由 之 Extension Method

在Unity3D提供的几种脚本语言中,有很多理由爱上C#,在我心目中Extension Method无疑是其中一个。

在使用Unity3D提供的类库书写脚本时,是否经常有类似这样的抱怨:“为什么就不能为AAA类写一个XXX方法呢?!明明很简单的一件事,现在却需要绕这么多圈子!”例如下面这3行代码:

明明很简单的三件事,但是代码写出来却不怎么简洁明了:

  • 设置X坐标为3
  • 设置等比缩放为(3,3,3)
  • Log一段话

对于Unity开发者,前两行代码估计都写过,而且很可能是需要常常写。第三行的Log代码我使用了string.Format——我喜欢更接近自然语言的Log输出,因为它会让那些调试信息看起来不那么烦人,但是每次都写一遍string.Format和一堆括号确实是又麻烦又冗长。

假如我们换一种写法:

是不是更加易懂而且代码也更加简洁了呢?我给Transform添加了两个梦寐以求”的方法:SetPositionX(float)以及SetUniformLocalScale(float),并且给所有继承自Object的类添加了一个Log(string, args)方法,可以直接传入string.Format的参数。

要实现这样的扩展无需破解Unity的类库,只需要使用C#的Extension Method即可。顾名思义,Extension Method允许你从外部为已有的类添加“扩展方法”——而且无需该类的任何代码。例如上面三个Extension Method的脚本是这样书写的:

从上面的代码不难看出,Extension Method要求必须使用静态类封装,且需要依据这样的格式为方法命名:

这里面this在函数传参中的使用也算是C#中this的一种特殊用法。

虽然Extension Method善加使用可以减少一定的重复工作量,让脚本更加简洁易读,但它也不是万灵药,在书写过于复杂的Extension Method之前也许你需要慎重考虑是否应该为该类增添一个新的接口,而不是“把代码写在外部”。另外struct是无法定义Extension Method的,例如Unity中的Vector3和Color。

最后附上两个我做的Extension Method脚本,分别针对Transform和Debug做了几个扩展方法,相信在看了这两个脚本后,你一定可以自己动手写出那些“梦寐以求”的扩展方法了。

点击下载示例脚本

发表评论

电子邮件地址不会被公开。 必填项已用*标注