【问题标题】:C# Delegate Instantiation vs. Just Passing the Method Reference [duplicate]C# 委托实例化与仅传递方法引用 [重复]
【发布时间】:2010-02-02 01:10:40
【问题描述】:

我有一个简单的问题:实例化 C# 委托与仅传递函数引用相比有什么优势?我的意思是:

为什么这样做:

Thread t = new Thread(new ThreadStart(SomeObject.SomeMethod));

什么时候可以做:

Thread t = new Thread(SomeObject.SomeMethod);

根据我的经验,两者都可以编译和工作......我错过了什么吗?

【问题讨论】:

    标签: c# .net methods delegates instantiation


    【解决方案1】:

    只要方法组SomeObject.SomeMethod 有一个返回类型为void 的方法并且不带参数就没有区别。这是因为ThreadStart 被定义为返回void 并且不接受任何参数的delegate,因此存在从方法组SomeObject.SomeMethodThreadStart 的隐式转换。因此,两者都在调用Thread 构造函数的重载Thread(ThreadStart)

    语言规范的相关部分是§6.6(方法组转换)。

    我有一个简单的问题:实例化 C# 委托与仅传递函数引用相比有什么优势?

    所以,这里只是对术语的更正。与

    class MyObject {
        public void SomeMethod() { }
    }
    
    MyObject someObject = new MyObject();
    

    someObject.SomeMethod 表示的东西是一个方法组。您可以将其视为可以使用符号someObject.SomeMethod 查找的一组重载方法。

    【讨论】:

    • someObject.SomeMethod()也是方法组吗?
    • @John Feminella:不,那将是一个方法调用。
    • 嗯,好的。如果SomeMethod 有多个签名匹配SomeMethod(...) 的重载,其中... 是任意参数怎么办?那么它是否是一个方法组,因为它可以引用几种方法之一并且尚未解决?
    • @John Feminella:对不起,我不清楚你的问题。您是否在询问调用表达式。例如,someObject.SomeMethod(parameter1, parameter2, ..., parametern),其中每个parameterj 都是一个表达式,ref variable referenceout variable reference?对于这样的表达式,要么存在最适用的重载(规范的第 7.4.3 节),要么尝试将表达式作为扩展方法调用进行处理,要么发生编译时错误;需要明确的是:模棱两可的调用是编译时错误。你问的是这个吗?
    • 我可能误解了方法组是什么。我要离开你的最后一句话,它说它是“可以使用符号查找的一组重载方法......”。如果我写SomeMethod(a, b) 并且有几个重载可以匹配这些参数(即使一个最终通过重载解析规则被解析为正确的),那是一个方法组吗?
    【解决方案2】:

    编译器会推断,当您键入较短的代码时,您的意思是较长的代码。最终效果没有区别。如果你想要完整构造函数的清晰,你可以把它放进去;如果您只想要方法组的简洁性,您可以允许编译器推断构造函数。这只是一种风格选择。

    【讨论】:

      【解决方案3】:

      这是等价的。关于该主题的良好介绍性文章:C# Delegates, Anonymous Methods, and Lambda Expressions – O My!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-10
        • 2021-11-21
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 2012-04-02
        相关资源
        最近更新 更多