N8,
The reason this happens is that when you create a delegate, the delegate
itself holds a reference to the object that the method is on. This way,
when you set the original reference to null, and do a GC, the object still
lives, because you are holding the delegate, which holds the object.
A copy of the object is not made, but rather, the original is just kept
alive because you are holding a reference (indirectly through the delegate)
to it.
Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
-
(E-Mail Removed)
"N8" <(E-Mail Removed)> wrote in message
news:C9B44D74-B947-45B8-9938-(E-Mail Removed)...
>I am trying to get an exception to occur and consequently found that when
> adding a target method to a delegates invocation list, a copy of that
> object
> is added instead of a reference to the object.
>
> Here's what I'm trying to do... I am iterating through the invocation list
> invoking each delegate manually. I want to eventually try to invoke a
> delegate to an object that has been destroyed. I'm essentially looking to
> get
> the exception "object not set to an instance of an object" or some kind of
> exception.
>
> I've created two classes to test with, one class has a delegate as
> follows:
>
> public class classContainsDelegate{
> public delegate void takesOneString(string message);
> public takesOneString myStringEvent;
>
> public void raiseEvent(string message){
> if(myStringEvent != null){
> foreach(takesOneString d in myStringEvent.GetInvocationList()){
> d(message);
> }//foreach
> }//if
> }//raiseevent
> }//class
>
>
> I have another class that is going to simply display the message, when
> called by the above delegate:
>
> public class classBeingCalledBack(string key){
> private string key = "";
>
> public classBeingCalledBack(string theKey){
> key = theKey;
> }//new method
>
> public string Key{
> get{return key;}
> }//key property
>
> public void theCallback(string message){
> Console.WriteLine("theCallback received '{0}' by '{1}', message, key);
> }//the callback
> }//class
>
>
> My test routine starts out like this:
>
> classContainingDelegate d1 = new classContainingDelegate();
> classBeingCalledBack o1 = new classBeingCalledBack("first instance");
> classBeingCalledBack o2 = new classBeingCalledBack("second instance");
>
> d1.myStringEvent += new
> classContainingDelegate.takesOneString(o1.theCallBack);
> d1.myStringEvent += new
> classContainingDelegate.takesOneString(o2.theCallBack);
>
> d1.raiseEvent("message #1");
>
> When I run this test, the 2 callbacks are made to both objects and I see
> the
> messages being displayed that the callbacks happened for objects keyed
> "first
> instance" and "second instance".
>
> Now I want to kill the "first instance" object altogether. I want to cause
> an exception when the delegate goes to make a callback to an object that
> shouldn't exist anymore. So I then add the following lines to my test
> routine:
>
> o1 = null;
> d1.raiseEvent("message #2");
>
> When doing this, I still get both callbacks still. No exceptions being
> thrown!
>
> Now, even if I go and change o1 like:
> o1 = new classBeingCalledBack("first instance - version 2");
>
> When the delegate is called for "o1", I would expect to see a message
> that
> the callback occurred for "first instance - version 2", but instead I see
> "first instance" which should have been overwritten.
>
> I have tried forcing a garbage collection, no difference.
>
> I have tried creating an Event instead of using a delegate (yeah I know
> its
> the same thing, but the rules slightly differ between the two) and no
> difference.
>
> Anybody have any ideas? What am I doing wrong or not getting here?
>
> Thanks in advance.