简体   繁体   English

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

[英]C# - Can't declare delegate within a method

I'm really blanking out here. 我真的在这里搞砸了。

I'm wondering why I can't declare a delegate type within a method, but rather I have to do it at a class level. 我想知道为什么我不能在方法中声明委托类型,而是我必须在类级别执行它。

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());};
        }


    }
}

Edit: I'm researching Lambda Expressions and backing up into how it was before Lambdas, for my own personal knowledge. 编辑:我正在研究Lambda表达式,并根据我个人的知识对Lambdas之前的表达进行备份。

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

It throws an error, because it's a type definition, not a variable declaration. 它抛出一个错误,因为它是一个类型定义,而不是一个变量声明。 Any type definition is not allowed inside method. 在方法内部不允许任何类型定义。 It's allowed only at class scope, or namespace scope. 它只允许在类范围或命名空间范围内。

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

By the way, why don't you write this: 顺便问一下,你为什么不写这个:

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

It's called lambda expression. 它被称为lambda表达式。

You can't declare any type inside a method. 您不能在方法中声明任何类型。 So let's consider the question "why can I not declare a type inside a method in C#?" 那么让我们考虑一个问题“为什么我不能在C#中的方法中声明一个类型?”

The answer to questions of this form is always the same. 这种形式的问题的答案总是一样的。 In order for you to be able to do something in C#, the following things all have to happen: 为了使您能够在C#中执行某些操作,必须执行以下操作:

  • Someone has to think of the feature 有人必须考虑这个功能
  • Someone has to design the feature 有人必须设计这个功能
  • Someone has to write the specification of the feature 有人必须编写该功能的规范
  • Someone has to implement that specification 有人必须实现该规范
  • Someone has to test the implementation 有人必须测试实现
  • Someone has to document the feature (and translate the documentation into a dozen different languages.) 有人必须记录该功能(并将文档翻译成十几种不同的语言。)
  • Somehow the implementation code has to get into a "vehicle" by which it can be shipped to customers. 不知何故,实施代码必须进入“车辆”,通过它可以将其运送给客户。

So far, of the things on that list only the first one has happened. 到目前为止,该列表中的内容只发生了第一个。 The rest of them haven't ever happened, so you can't use that feature in C#. 其余的都没有发生过,所以你不能在C#中使用这个功能。

You seem to imply that the default state of a feature is "implemented" and that we have to come up with some reason to make it not implemented. 您似乎暗示功能的默认状态是“已实现”,并且我们必须提出一些使其未实现的原因。 I assure you that's not the case; 我向你保证,情况并非如此; the default state of all possible features is "not implemented", and we have to have a justification for spending the time, money and effort it takes to implement a feature. 所有可能功能的默认状态是“未实现”,我们必须有理由花费时间,金钱和精力来实现功能。 So far no one has made a compelling case that local type declarations are worthwhile; 到目前为止,没有人提出一个令人信服的案例,即本地类型声明是值得的; if you'd like to try to make a compelling case, I'd love to hear it. 如果你想尝试做出令人信服的案例,我很乐意听到。

Declaring a delegate inside a method would be like declaring a class inside a method because the compiler rewrites the delegate declaration onto a class declaration. 在方法中声明委托就像在方法中声明一个类,因为编译器将委托声明重写为类声明。

This is why you can't do this while it's perfectly valid do assign to a delegate type. 这就是为什么你不能做到这一点,而它完全有效, 分配给委托类型。

Being able to create arbitrary delegates any time you want is useful, but giving them distinct but anonymous types seems far less useful. 能够随时创建任意委托是有用的,但是给它们不同但匿名的类型似乎没那么有用。

With or without lambdas, you could just replace anon_delgate ad with Action<int> . 无论有没有lambda,你都可以用Action<int>替换anon_delgate ad Since nobody outside method can see anon_delegate , its existence doesn't add extraordinary value. 由于没有外部方法可以看到anon_delegate ,它的存在不会增加非凡的价值。 You want to define the delegate type locally, but you could encode any information about the purpose of the delegate inside the variable's name rather than in the variable's type. 您希望在本地定义委托类型,但您可以在变量名称内而不是在变量类型中编码有关委托目的的任何信息。 The dozens of already defined* Action and Func delegates make it very rare that you'll be unable to find a delegate that suits your needs. 数十个已经定义的* ActionFunc代表使您很难找到适合您需求的委托。

In short, I see this feature as adding some heavy costs per Eric, but don't see it as adding enough benefits to offset those costs, nevermind offsetting the additional confusion that comes from providing another feature that might confuse developers. 简而言之,我认为这个功能为每个Eric增加了一些沉重的成本 ,但是没有看到它增加了足够的好处来抵消这些成本,从未抵消因提供可能使开发人员困惑的另一个功能而产生的额外混乱。

This feature doesn't add any expressive power to the language, its nonexistence is easily worked around, and I think would waste more developer time (by making C# harder to learn/use) than it would save. 此功能不会为语言添加任何表达能力,它的不存在很容易解决,我认为会浪费更多的开发人员时间(通过使C#更难学习/使用)而不是保存。

*(well, less of them in older versions of C#, but asking why a feature isn't in an older version of C# when it could be useful is pretty unexciting when the answer is, "wow, that is useful. We added it to the next version.") *(当然,少用它们的旧版本的C#,但问为什么一个功能在旧版本的C#时,它可能是有用的很平平无奇的时候,答案是,“哇,这有益的。我们增加了它到下一个版本。“)

你为什么不只使用lambda表达式?

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

Because a delegate is a public method signature intended for a user of the class to comply with on their end. 因为委托是一个公共方法签名,旨在让类的用户遵守它们的目的。 It's a way of saying "if you expose this method with these parameters, I can call it when necessary". 这是一种说法“如果你用这些参数公开这个方法,我可以在必要时调用它”。

Method internals are not exposed outside of the class - just the signature - so declaring a method signature within what is private to the class doesn't make sense. 方法内部不暴露在类之外 - 只是签名 - 因此在类的私有内部声明方法签名没有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM