简体   繁体   中英

Can a C# object "kill" itself?

In C#, can an object method invoke the object's own d-tor? and making any reference to the object invalid?

I'm trying to build an "object control" in memory system. user can "checkout" an object, then "finish" working with it ("checkin"). and I need to be sure once the object is "checked in" - any reference to it in the user code, will become invalid.

Here is an illustrated situation

public class MyType
{
     public object Object {get; private set;}

     public MyType()
     {
         this.Object = new ... ; // initialize Object property
     }

     public void Finish()
     {
         // ... some work on this.Object

         this.Object = null;
         // this = null;   <- kill myself ?
     }
}

pubic class Consumer()
{
   public void Method()
   {
        var myUsage = new MyType(); // underline Object is initialized

        SomethingWith(myUsage.Object); // use underline Object

        myUsage.Finish();              // complete the usage

        SomethingWith(myUsage.Object); // <-- exception, myUsage is not valid, is null or something similar
   }

   public void SomethingWith(object obj)
   {
       obj.Method(); 
       ....
   }
}

No, this is not possible. The Garbage Collector is very careful about not causing any leaked references. Therefore if somebody still has a reference to an object, it's not possible to prevent that he's manipulating it.

For what you need to do, you need to store the logic about accessibility within the object (or a common base class of it). So that your object can track when it's "owned" and when not. This will probably be ugly, as you have to secure all public methods as well as all properties from being accessed while the object is not owned. As an extra complexity, you need to make sure the access only happens from whoever actually owns the object and not from somebody else.

I don't know your exact use case there, but I would suggest to use proper locking within the object, so that it does not have to care about who accesses it, but it still keeps a consistent state.

I think that you should avoid to allow direct access to nested object: you can create a method on MyType class that internally it access to the nested object, eg

public void DoSomething(){
   if(_nestedObject!=null) {
     _nestedObject.DoSomething();
   }
}

As extra check, you could replace the call to Finish method with the IDisposable pattern. You implement IDispose interface, then you use you class as belove

using(var wrapper =new MyType()) {
  wrapper.DoSomething();
}

I believe it's possible for an object to request to be killed. It would rely on the parent object to perform the task upon request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM