C# - 无法在方法中声明委托

时间:2011-09-15 17:16:13

标签: c# .net delegates

我真的在这里消隐。

我想知道为什么我不能在方法中声明委托类型,而是我必须在类级别执行它。

namespace delegate_learning
{
    class Program
    {
        // Works fine
        public delegate void anon_delgate(int i);

        static void Main(string[] args)
        {
            HaveFun();
            Console.Read();
        }

        public static void HaveFun()
        {
            // Throws an error :/
            //delegate void anon_delgate(int i);

            anon_delgate ad = delegate(int i) { Console.WriteLine(i.ToString());};
        }


    }
}

编辑:我正在研究Lambda表达式,并根据我个人的知识对Lambdas之前的表达进行备份。

6 个答案:

答案 0 :(得分:18)

// Throws an error :/
delegate void anon_delgate(int i);

它会抛出错误,因为它是类型定义,而不是变量声明。方法内不允许任何类型定义。它只允许在类范围或命名空间范围内。

namespace A
{
   delegate void X(int i); //allowed
   public class B
   {
         delegate void Y(int i); //also allowed
   }
}

顺便问一下,你为什么不写这个:

anon_delgate ad = i => Console.WriteLine(i.ToString());

它叫做lambda表达式。

答案 1 :(得分:12)

您无法在方法中声明任何类型。那么让我们考虑一个问题“为什么我不能在C#中的方法中声明一个类型?”

这种形式的问题的答案总是一样的。为了使您能够在C#中执行某些操作,必须执行以下操作:

  • 有人必须考虑这个功能
  • 有人必须设计功能
  • 有人必须编写功能的说明
  • 有人必须实施该规范
  • 有人必须测试实施
  • 有人必须记录该功能(并将文档翻译成十几种不同的语言。)
  • 不知何故,实施代码必须进入“车辆”,通过它可以将其运送给客户。

到目前为止,该列表中的内容只发生了第一个。其余的都没有发生过,所以你不能在C#中使用这个功能。

您似乎暗示功能的默认状态是“已实现”,并且我们必须提出一些使其未实现的原因。我向你保证,情况并非如此;所有可能功能的默认状态是“未实现”,我们必须有理由花费时间,金钱和精力来实现功能。到目前为止,没有人提出一个令人信服的案例,即本地类型声明是值得的;如果你想尝试做出令人信服的案例,我很乐意听到它。

答案 2 :(得分:3)

在方法中声明委托就像在方法中声明一个类,因为编译器会将委托声明重写为类声明。

这就是为什么你无法做到这一点,而完全有效的指定到委托类型。

答案 3 :(得分:2)

能够随时创建任意委托是有用的,但是给它们不同但匿名的类型似乎没那么有用。

无论有没有lambdas,您都可以将anon_delgate ad替换为Action<int>。由于没有任何外部方法可以看到anon_delegate,因此它的存在不会增加非凡的价值。您希望在本地定义委托类型,但您可以在变量的名称中编码有关委托目的的任何信息,而不是在变量的类型中。数十名已定义的* ActionFunc代表非常难以找到符合您需求的代表。

简而言之,我认为这个功能为每个Eric增加了一些heavy costs,但是没有看到它增加了足够的好处来抵消这些成本,从来没有抵消因提供可能混淆的另一个功能而产生的额外混乱开发者。

此功能不会为语言添加任何表达能力,它的不存在很容易解决,我认为会浪费更多的开发人员时间(使C#更难学习/使用)而不是保存。

*(好吧,在较旧版本的C#中它们较少,但是当问题解决时,问问为什么某个功能不适用于旧版本的C#,当答案是,“哇,有用。我们将它添加到下一个版本。“)

答案 4 :(得分:1)

为什么不使用lambda表达式?

Action<int> ad = i => Console.WriteLine(i.ToString());

答案 5 :(得分:0)

因为委托是一个公共方法签名,旨在让类的用户遵守它们的目的。这是一种说法“如果你用这些参数公开这个方法,我可以在必要时调用它。”

方法内部不会暴露在类之外 - 只是签名 - 因此在类的私有内部声明方法签名是没有意义的。