tags:

views:

114

answers:

3

What is the reason why I can't put parenthesis after my Method name when assigning it to a delegate type.

Here is code:

public delegate Simple Simple(); //Create a delegate that returns its own type.

class Program
{
    public class Exercise
    {
        public static Simple Welcome()
        {
            Console.WriteLine("Welcome!");
            return null;

        }
    }
    static void Main(string[] args)
    {
        Simple msg;
        msg = Exercise.Welcome(); //Since Welcome returns Simple, I can execute it.

        msg();
        Console.Read();
    }
}
+12  A: 

It lets the compiler distinguish a method call from a reference to a method group. If you add parenthesis, the compiler will call the method and uses the return value of that method call, instead of the method group itself.

Mehrdad Afshari
So Welcome(); would be like calling the method, whereas, Welcome; is a reference to the method. Do I have that right? I feel stupid, lol.
Xaisoft
Yes. You got it right.
Mehrdad Afshari
As I mentioned in another comment to the other poster, I asked if it is actually possible to assign a delegate and call it at the same time.
Xaisoft
Reference to a method *group*. The distinction matters because methods can have overloads.
Joren
@Joren: thanks for the comment. edited the answer to reflect.
Mehrdad Afshari
I updated my code with comments, are the comments correct about executing a delegate and assigning it at the same time.
Xaisoft
No, they're not. You're executing a _method_ (not a delegate), and you're assigning the _return value of that method_ to a variable. You aren't executing a method and creating a delegate _to the same method_ at the same time (unless `Simple` returns itself).
Pavel Minaev
So, in my case, I am actually returning null to msg.
Xaisoft
Is null a value type or reference type? If my method Welcome returns Simple in its declaration, why does Simple msg = Exercise.Welcome(); still work if I am not returning Simple. Shouldn't it give me an error saying something like can't convert null to simple, something like that?
Xaisoft
`null` is not a type, it's a value, but it's compatible with all reference types, nullable value types, and unmanaged pointer types (and only with them). Delegates are reference types, which is why you can assign `null` to a delegate (and therefore why your updated code works).
Pavel Minaev
+4  A: 

Because () executes the method. And as you said yourself, you're assigning it, not executing it. If you used parentheses where you indicate, you'd be assigning the result of executing the method, not assigning the method.

Greg Beech
When I put parenthesis, it gives me an error anyway, so I guess this is built into the compiler to check this.
Xaisoft
I just thought of something, what if I actually wanted to assign it and call it at the same time. Is this possible or not?
Xaisoft
No, why would you want it? If you want to assign and call, then 1) assign, and 2) call :)
Pavel Minaev
@Pavel, lol, I knew that would be the answer, I just thought if it was actually possible to do.
Xaisoft
@Xaisoft - You can't assign the result of executing the method, because the method returns void. If the method returned a Simple then you could assign that to the delegate.
Greg Beech
Ok, that makes sense, that is actually what the compiler gave me as a warning.
Xaisoft
+4  A: 

Consider this code:

delegate Foo Foo(); // yes, this is legal - a delegate to method that returns
                    // the same kind of delegate (possibly to a different method,
                    // or null)

class Program
{
    static Foo GetFoo() { return null; }

    static void Main()
    {
         Foo foo;

         foo = GetFoo;   // assign a delegate for method GetFoo to foo

         foo = GetFoo(); // assign a delegate returned from an invocation
                         // of GetFoo() to foo
    }
}

Hopefully it makes it clear why the parentheses have to be significant.

Pavel Minaev
Is the line delegate Foo Foo() actually returning the same type of delegate or is it return some user defined type like a class or structure?
Xaisoft
foo = GetFoo(); is confusing.
Xaisoft
if you omit foo = GetFoo;, I am assuming it will not work, correct. Am I on the right track here? foo = GetFoo; puts the type Foo into foo, so then food = GetFoo(); is valid. Did I understand that correctly?
Xaisoft
Ok, it makes more sense now after updating my code, I will update it on here with comments.
Xaisoft
No, the lines are completely independent. You can omit one or the other.
Pavel Minaev
Yes, I just found that out by editing my code. I updated it on the question, are the comments correct?
Xaisoft
What's confusing about `foo = GetFoo()`? Delegates are just objects (and delegate types are just classes derived from `System.Delegate`) with a bit of magic that lets instances be created "from methods". And there's nothing wrong with methods returning objects, therefore, there's nothing wrong with methods returning delegates. `Foo Foo()` is a delegate to a method returning a delegate.
Pavel Minaev
The idea here was to highlight that `foo = GetFoo;` and `foo = GetFoo();` are two very different things. In the edited question, I'm not sure what the question even is now :)
Pavel Minaev
It is not confusing anymore. I guess the confusing part was I am thinking if I have something like public MyClass ReturnClass() and MyClass is not defined yet, this would not work, but I guess delegates behave differently. Do you see what I am saying?
Xaisoft
I wanted to make sure my comments in the edited question (comments in the code) were correct.
Xaisoft
You can always use the name of the class within the definition of that same class (i.e. you can define class which has property, the type of which is that same class). Delegates follow that pattern there, so you can declare a delegate type which references itself. I guess it's somewhat less intuitive for delegates because of their syntax.
Pavel Minaev