0

Delegate are reference type but still when trying to pass it to a method it requires a ref keyword.

This reminds me of string that requires ref to be modified within a method because they are immutable, are delegate immutable?

Here is my mini project:

delegate void MyDel();
static void Main(string[] args)
{
    MyDel _del  = new MyDel(Idle);

    while(true)
    {
        if(_del != null)
            _del();  
            int c = Console.Read();
            AI(c,ref _del);
            Console.Read();
            Console.Read();
        }
    }
}
    static void AI(int c, ref MyDel del) 
    {
        if(c == 'a')
        {
            del = Attack;
        }else if(c == 'i'){
            del = Idle;
        }else if (c == 's'){
            del = SwingSword;
        }
        else if (c == 'w')
        {
            del = Attack;
            del += SwingSword;
        }
        else {
            del = Idle;
        }
    }

Without the ref keyword I am back to the swap method case where things happen only inside the method.

Can anyone tell me why delegates need to be passed by reference?

0

2 Answers 2

4

The reason you have to use ref is because you are changing the delegate that _del refers to.

Change your code to the following and you won't need the ref parameter:

static MyDel AI(int c) 
{
    if(c == 'a')
    {
        return Attack;
    }
    if(c == 'i')
    {
        return Idle;
    }
    if (c == 's')
    {
        return SwingSword;
    }
    if (c == 'w')
    {
        return (MyDel)Attack + SwingSword;
    }
    return Idle;
}

C# does not pass by reference unless you specify the ref keyword. However, since the value of a variable of a delegate type is a reference to a method, the value passed is a reference. Use the ref keyword and you pass a reference to the variable's store, not the method, thus it becomes possible to change its value.

If the previous paragraph is as clear as mud, take a read of https://stackoverflow.com/a/8708674/7122, which is a very good explanation of pass by value vs pass by reference.

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

4 Comments

Ok That is what I had in the first place but did not know about the possibility to use Attack + SwingSword. And your explanation makes sense, at least to me.
Is there any reason why return Attack+ SwingSword; shows as error in VS? I fixed it declaring a new delegate and assigning both method but what you show seems wrong.
@fafase Apologies, I should have checked the code before posting. It needs a cast so that it knows it's adding a MyDel to a MyDel, rather than just any old method group to another. Code updated.
Indeed :), now we are friends again. Thanks for it all.
3

This is not about immutability. You are assigning a new value to a variable declared in an outer scope, and you want the outer scope to be aware of this assignment - that's why you need ref.

This would be true for any type.

*Edit

"Outer scope" is not actually the best term. "The calling method's scope" is what I meant.

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.