[Orcas] 8. Partial method

[ 2007-09-08 15:53:09 | 作者: yuhen ]
字号: | |
C# 3.0 (Beta2) 引入 Partial Method 来进一步增强 Partial Class 的能力。Partial Method 和 Partial Class 一样更多的是为了 "Code Generation" 而产生。

我们先看一个例子。
partial class Program
{
    static void Main(string[] args)
    {
        Test();
    }

    static partial void Test();
}

反编译
.class private auto ansi beforefieldinit Program
    extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: call instance void [mscorlib]System.Object::.ctor()
        L_0006: ret 
    }

    .method private hidebysig static void Main(string[] args) cil managed
    {
        .entrypoint
        .maxstack 8
        L_0000: nop 
        L_0001: ret 
    }
}

我们发现上面这个例子中,编译器并没有把 Partial Method 编译到最终程序集中,这有点像 ConditionalAttribute。我们试着 "完成" 这个分部方法,看看会是什么样子。
partial class Program
{
    static void Main(string[] args)
    {
        Test();
    }

    static partial void Test();
    static partial void Test()
    {
        throw new NotImplementedException();
    }
}

反编译
.class private auto ansi beforefieldinit Program
    extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: call instance void [mscorlib]System.Object::.ctor()
        L_0006: ret 
    }

    .method private hidebysig static void Main(string[] args) cil managed
    {
        .entrypoint
        .maxstack 8
        L_0000: nop 
        L_0001: call void Learn.CUI.Program::Test()
        L_0006: nop 
        L_0007: ret 
    }

    .method private hidebysig static void Test() cil managed
    {
        .maxstack 8
        L_0000: nop 
        L_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
        L_0006: throw 
    }
}

看来这依旧是编译器玩的技巧,最终和 Partial Class 一样会恢复成 "正常" 模样。

限制:
  • 只能用于 Partial Class、Partial Struct 中。
  • 如果是静态方法,则 Partial 必须放在 static 关键词后面。
  • 返回类型必须是 void。
  • 方法参数支持 ref 关键字,但不支持 out。
  • 不能添加 virtual、abstract、override、new、sealed、extern 访问修饰。
  • 必须是 private 方法 (但不能包含 private 关键字)。
  • 我们不能定义多个签名相同的 Partial Method。
  • 我们不能在多处实现 Partial Method。
  • 不能和现有方法签名相同。
Partial Method 在 LINQ to SQL 中被频繁使用。
public partial class DataClasses1DataContext : System.Data.Linq.DataContext
{
    partial void OnCreated();

    public DataClasses1DataContext(string connection) :
        base(connection, mappingSource)
    {
        OnCreated();
    }
}

Partial Method 带来一种 "模式" 上的变化,我们可以事先为一种调用 (Method Call) 提供一个 "占位",但最终调用与否可以交给 "另外的实现者",同时编译器的 "智能" 保证了这种额外的 "冗余" 不会存在性能问题。可以说 Partial Method 的出现让 Partial Class 真正成熟起来,可以想象 Partial Class 也会因此从 "Code Generation" 走向更广阔的天地。

应用场景:

1. 替代 ConditionalAttribute,将调试代码写到另外的 Partial Class + Partial Method 中。
2. 多人合作时,可以提前定义方法签名,无需等待实现。
3. ......
[最后修改由 yuhen, 于 2008-09-14 14:46:37]
评论Feed 评论Feed: http://www.rainsts.net/feed.asp?q=comment&id=560

这篇日志没有评论。

发表评论
表情图标
[smile] [confused] [cool] [cry]
[eek] [angry] [wink] [sweat]
[lol] [stun] [razz] [redface]
[rolleyes] [sad] [yes] [no]
[heart] [star] [music] [idea]
UBB代码
转换链接
表情图标
悄悄话
用户名:   密码:  
验证码 * 请输入验证码