如何删除对象?

use*_*055 5 c# memory-management

我需要创建一个删除实例的类方法.

public class Car
{
    private string m_Color;

    public string Color
    {
        get { return m_Color; }
        set { m_Color = value; }
    }

    public Car()
    {
    }

    public void Delete()
    {
        /*This method will delete the instance,
        so any references to this instance will be now null*/
    }
}

class Program
{
    static void Main( string[] args )
    {
        Car car = new Car();

        car.Delete();

        if(car==null)
            Console.WriteLine("It works.");
        else
            Console.WriteLine("It doesn't work.")
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有任何可能的解决方案(即使不推荐)如何做到这一点.

这个类的实例将存储在数百个不同的类中.我将尝试描述这个,例如会有这些类:

public class CarKey
{
    private Car m_Car;

    public Car Car
    {
        get { return m_Car; }
    }

    public bool CarExist{ get{ return m_Car != null; } }

    public CarKey( Car car )
    {
        m_Car = car;
    }
}

public class Garages
{
     private List<Car> m_Collection = new List<Car>();

     private int m_Size;

     public int Size{ get{ return m_Size; } }

     public Garages( int size )
     {
         for(int i=0;i<size;i++)
             m_Collection.Add(null);
     }

     public bool IsEmpty( int garage )
     {
         return m_Collection[garage] == null;
     }

     public void InsertCar( Car car, int garage )
     {
          if( m_Collection[garage] != null )
            throw new Exception("This garage is full.");

          m_Collection[garage] = car;
     }


     public Car GetCar( int garage )
     {
         if( m_Collection[garage] == null )
           throw new Exception("There is no car, maybe it was deleted.");

         return m_Collection[garage];
     }
}
Run Code Online (Sandbox Code Playgroud)

Roh*_*ats 14

从任何类中,您都无法将其值设置为null.这是不允许的,也没有意义 -

public void Delete()
{
    this = null; <-- NOT ALLOWED
}
Run Code Online (Sandbox Code Playgroud)

你需要一个类的实例来调用Delete()方法,所以一旦你完成它,为什么不将该实例设置为null.

Car car = new Car();
// Use car objects and once done set back to null
car = null;
Run Code Online (Sandbox Code Playgroud)

无论如何,你想要实现的是C#中无法实现的.我怀疑你的问题,你想要这个,因为你当前的设计中存在内存泄漏,这不会让Car实例消失.我建议你更好地描述你的应用程序,并确定停止GC收集汽车实例的区域,并努力改善该领域.


小智 6

我建议,如果您想在使用后发布实例,请使用.Net的IDisposable接口.

请参阅下面的示例实现.

public class Car : IDisposable
{

   public void Dispose()
   {  
      Dispose(true);
       // any other managed resource cleanups you can do here
       Gc.SuppressFinalize(this);
   }
   ~Car()      // finalizer
   {
        Dispose(false);
   }

   protected virtual void Dispose(bool disposing)
   {
     if (!_disposed)
     {
      if (disposing)
      {
        if (_stream != null) _stream.Dispose(); // say you have to dispose a stream
      }

      _stream = null;
    _disposed = true;
    }

   }
}
Run Code Online (Sandbox Code Playgroud)

现在在您的代码中:

void main()
{
   using(var car = new Car())
   {
     // do something with car
   } // here dispose will automtically get called. 
}
Run Code Online (Sandbox Code Playgroud)


Lee*_*Lee 5

听起来您需要为一个可以失效的实例创建一个包装器:

public class Ref<T> where T : class
{
    private T instance;
    public Ref(T instance)
    {
        this.instance = instance;
    }

    public static implicit operator Ref<T>(T inner)
    {
        return new Ref<T>(inner);
    }

    public void Delete()
    {
        this.instance = null;
    }

    public T Instance
    {
        get { return this.instance; }
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

Ref<Car> carRef = new Car();
carRef.Delete();
var car = carRef.Instance;     //car is null
Run Code Online (Sandbox Code Playgroud)

但是请注意,如果任何代码将内部值保存在变量中,则不会通过调用Delete.