Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Delegate passed as parameter issue

Tags:

c#

delegates

Confused by C# delegate passing as parameter:

class Program
{
    static void Main(string[] args)
    {
        var a = new A();
        Action holder = delegate{};
        //a.Attach1(holder); //nothing printed
        a.Attach2(ref holder);//print as expected

        holder();
    }
}

public class A
{
    private void P1()
    {
        Console.WriteLine("Inaccessible");
    }
    public void P2()
    {
        Console.WriteLine("Accessible");
    }
    public void Attach1(Action holder)
    {
        holder += P1;
        holder += P2;
    }
    public void Attach2(ref Action holder)
    {
        holder += P1;
        holder += P2;
    }
}

delegate is reference type, why does it still need to be passed with ref in font to work correctly as in Attach2, something like value type?

From C++ experience, delegate is just a function pointer, Attach1(Action holder) is something like Attach1(Action* holder), the origial holder is passed as 'value', thus not assigned, while in the second case, Attach2(ref Action holder) is something like Attach1(Action** holder), the pointer is actually passed, thus can be manipulated correctly. But why in .NET there is no indication or hint???

like image 533
user950851 Avatar asked Nov 22 '25 15:11

user950851


1 Answers

Because a delegate instance is immutable, and += is a new assignment to a new delegate instance; it is basically:

holder = (Action)Delegate.Combine(holder, P1);
holder = (Action)Delegate.Combine(holder, P2);

If you don't pass that as ref, the new value will not be seen outside the method.

Or to put that in simpler terms - consider a string; a string is likewise immutable and += is an assignment. Now consider:

public void Append(string s) {
    s += "[suffix]";
}
public void Append2(ref string s) {
    s += "[suffix]";
}

If we call:

string x = "abc";
Append(x);
Console.WriteLine(x);

we will see abc. If we call

string x = "abc";
Append2(ref x);
Console.WriteLine(x);

we will see abc[suffix] - for the exact same reasons.

like image 178
Marc Gravell Avatar answered Nov 24 '25 04:11

Marc Gravell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!