let's say I've a class to manage a stack of delegates. For some reason, at some point I need to invalidate a random delegate on the stack so, since I pass a variable of a delegate as reference, I expect that setting to null that variable, will prevent the stack to invoke that method just testing if it is null, but instead happens that the reference to the method is still there and therefore will be called. Here some silly code to show what I mean:
public delegate void DlgtVoidVoid(); public class TestPile { Pile pileStack = new Pile(); DlgtVoidVoid _delvar1 = null; DlgtVoidVoid _delvar2 = null; public void Main() { _delvar1 = voidmethod1; _delvar2 = voidmethod2; pileStack.PushItem(ref _delvar1); pileStack.PushItem(ref _delvar2); //trying to invalidate the first delegate handler _delvar1 = null; pileStack.InvokeAndPop();//invoke 2 pileStack.InvokeAndPop();//shouldn't voidmethod1 call fail? //but instead also voidmethod1 will be called: why? } void voidmethod1() { Console.WriteLine("calling void method one"); } void voidmethod2() { Console.WriteLine("calling void method two"); } } and this is a little stack manager just for an example:
public class Pile { DlgtVoidVoid[] thepile = new DlgtVoidVoid[10]; int pileindex = -1; public void PushItem(ref DlgtVoidVoid item) { thepile[++pileindex] = item; } public DlgtVoidVoid PeekItem() { return thepile[pileindex]; } public DlgtVoidVoid PopItem() { return thepile[pileindex--]; } public void InvokeAndPop() { if(pileindex >= 0) { if(PeekItem() != null) PopItem().Invoke(); } } } It is obvious that passing with ref a reference variable in c# don't work as I would expect, let's say, in C++ or some, therefore is there a way to achieve that in C# or I must change that code logic?
refonly applies to the local variableiteminPushItem, you are storing a copy of the reference in the stack. When you set_delVar1tonullthat does not affect the copied stack reference.PushItem()by-ref here does no hing. You are still only putting a copy of the reference intothepile. Would suggest some different logic here.voidmethod1is called, because you only clear the reference from_delvar1to your function. Your Pile class has still a reference to the function.Pilewill never pop a null. Thus repeated calls toInvokeAndPop()would just keep checking a null reference without changing anything. Probably a bug.