C# 如何删除对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19476730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:05:27  来源:igfitidea点击:

How to delete object?

c#memory-management

提问by user1576055

I need to create a method of class that delete the instance.

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

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.")
    }
}

I want to know if there is any possible solution (even if it is not recommended) how to do this.

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

Instance of this class will be stored in hundreds of different class. I will try to describe this, for example there will be these classes:

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

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];
     }
}

回答by Rohit Vats

From any class you can't set its value to null. This is not allowed and doesn't make sense also -

在任何类中,您都不能将其值设置为 null。这是不允许的,也没有意义——

public void Delete()
{
    this = null; <-- NOT ALLOWED
}

You need an instance of class to call Delete() method so why not set that instance to null itself once you are done with it.

您需要一个类的实例来调用 Delete() 方法,所以为什么不在完成后将该实例设置为 null 本身。

Car car = new Car();
// Use car objects and once done set back to null
car = null;

Anyhow what you are trying to achieve is not possible in C#. I suspect from your question that you want this because there are memory leaks present in your current design which doesn't let the Car instance to go away. I would suggest you better profile your application and identify the areas which is stopping GC to collect car instance and work on improving that area.

无论如何,您想要实现的目标在 C# 中是不可能的。我从你的问题中怀疑你想要这个,因为你当前的设计中存在内存泄漏,这不会让 Car 实例消失。我建议您更好地分析您的应用程序并确定阻止 GC 收集汽车实例的区域并努力改进该区域。

回答by Rohit Vats

I would suggest , to use .Net's IDisposable interface if your are thinking of to release instance after its usage.

如果您想在使用后释放实例,我建议使用 .Net 的 IDisposable 接口。

See a sample implementation below.

请参阅下面的示例实现。

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;
    }

   }
}

Now in your code:

现在在您的代码中:

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

回答by FLCL

You can proxyfy references to your object with, for example, dictionary singleton. You may store not object, but its ID or hash and access it trought the dictionary. Then when you need to remove the object you set value for its key to null.

例如,您可以使用字典单例来代理对对象的引用。您可以不存储对象,而是存储它的 ID 或哈希值,并通过字典访问它。然后,当您需要删除对象时,将其键的值设置为 null。

回答by Lee

It sounds like you need to create a wrapper around an instance you can invalidate:

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

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; }
    }
}

and you can use it like:

你可以像这样使用它:

Ref<Car> carRef = new Car();
carRef.Delete();
var car = carRef.Instance;     //car is null

Be aware however that if any code saves the inner value in a variable, this will not be invalidated by calling Delete.

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

回答by Iulian Radulescu

You cannot delete an managed object in C# . That's why is called MANAGED language. So you don't have to troble yourself with delete (just like in c++).

您不能在 C# 中删除托管对象。这就是为什么被称为管理语言。所以你不必为删除而烦恼(就像在 C++ 中一样)。

It is true that you can set it's instance to null. But that is not going to help you that much because you have no control of your GC (Garbage collector) to delete some objects apart from Collect. And this is not what you want because this will delete all your collection from a generation.

确实,您可以将它的实例设置为 null。但这不会对你有多大帮助,因为你无法控制你的 GC(垃圾收集器)来删除除了收集之外的一些对象。这不是您想要的,因为这会删除一代人的所有收藏。

So how is it done then ? So : GC searches periodically objects that are not used anymore and it deletes the object with an internal mechanism that should not concern you.

那么它是如何完成的呢?所以:GC 会定期搜索不再使用的对象,并使用与您无关的内部机制删除该对象。

When you set an instance to null you just notify that your object has no referene anymore ant that could help CG to collect it faster !!!

回答by svick

What you're asking is not possible. There is no mechanism in .Net that would set all references to some object to null.

你问的是不可能的。.Net 中没有任何机制可以将对某个对象的所有引用设置为null.

And I think that the fact that you're trying to do this indicates some sort of design problem. You should probably think about the underlying problem and solve it in another way (the other answers here suggest some options).

而且我认为您尝试这样做的事实表明存在某种设计问题。您可能应该考虑潜在的问题并以另一种方式解决它(此处的其他答案提出了一些选择)。

回答by Stanislav Ageev

You can use extension methods to achive this.

您可以使用扩展方法来实现这一点。

public static ObjRemoverExtension {
    public static void DeleteObj<T>(this T obj) where T: new()
    {
        obj = null;
    }
}

And then you just import it in a desired source file and use on any object. GC will collect it. Like this:Car.DeleteObj()

然后您只需将其导入所需的源文件并在任何对象上使用。GC 会收集它。像这样:Car.DeleteObj()

EDITSorry didn't notice the method of class/all references part, but i'll leave it anyway.

编辑抱歉没有注意到类/所有引用部分的方法,但无论如何我都会留下它。

回答by user3761570

Use a collection that is a static property of your Carclass. Every time you create a new instance of a Car, store the reference in this collection.

使用作为Car类的静态属性的集合。每次创建 a 的新实例时Car,将引用存储在此集合中。

To destroy all Cars, just set all items to null.

要销毁所有Cars,只需将所有项目设置为null