15

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.

4
  • 7
    Can you declare any type within a method? Commented Sep 15, 2011 at 17:18
  • I think Nawaz's answer is a good one in that it emphasizes the different scope levels. What would be the benefits of scoping a delegate within a mehod, given that it wouldn't be communicable to other methods? Commented Sep 15, 2011 at 18:51
  • @Steven - One thing that comes off the top of my head, is that a benefit would be that you could scope it inside a method and directly assign it an anonymous method to use within the method you're declaring the delegate in. Commented Sep 16, 2011 at 16:35
  • @contactmatt - maybe I'm missing something obvious, but I still don't see the benefit there. If the delegate and method both reside solely within the scope of the owning method, what has accessing the anon method via the delegate bought you over directly accessing the anon method? Commented Sep 16, 2011 at 19:14

6 Answers 6

19
// 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.

Sign up to request clarification or add additional context in comments.

1 Comment

+0: I think this is somewhat begging the question. Contactmatt is asking why "Any type definition is not allowed inside method. It's allowed only at class scope, or namespace scope."
12

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#?"

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:

  • 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#.

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.

2 Comments

To the statement that yuo can't declare any types within methods, aren't anonymous types declared this way? I realize they are not scoped to them, but thats the only context in which you can define them. Or does the term "declare" mean something different for anonymous types in the lexicon?
@LBushkin: That's a good point. On the one hand, sure, it makes sense to say that an anonymous type is "defined" or "declared" or whatever, inside a method. But in another sense, anonymous types are not declared at all. I would say that to "declare" something is to introduce into a declaration space a mapping from a name to some entity. An anonymous type has no name, and therefore is never "declared".
5

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.

1 Comment

Or: because a delegate is a type, just like a class. How the compiler treats it is not the issue.
2

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>. Since nobody outside method can see anon_delegate, its existence doesn't add extraordinary value. 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.

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.

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.

*(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.")

Comments

1

Why don't you just use lambda expressions?

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

2 Comments

You can't assign a lambda to an implicitly-typed variable. (In this case, what would var be? Action<int>? Action<Foo>?)
Yes, I always forget that C# is limited... Fixed.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.