2013-10-20 58 views
4

我需要创建一个删除实例的类的方法。如何删除对象?

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

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

此类的实例将存储在数百个不同的类中。我会尽量说明这一点,例如会出现这些类:

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

而不是'car.Delete()'为什么不简单'car = null'? –

+3

/*此方法将删除实例,因此对此实例的任何引用现在都将为空* /因此有关空值的任何答案均不正确。 – FLCL

+0

我不能这样做。在我的程序中将有数百个参考文献在不同的地方和不同的格式,我无法管理它们。 – user1576055

回答

11

从你不能将其值设置为null任何类。这是不允许的,没有意义也 -

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

你需要的类的实例调用delete()方法,那么为什么不设置该实例为null本身,一旦你用它做。

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

总之你正在努力实现在C#中是不可能的。我怀疑你的问题 ,因为你目前的设计中存在内存泄漏 ,它不会让Car实例去掉 。我建议你更好地描述你的应用程序,并确定停止GC收集汽车实例的区域,并且 确定改善该区域的工作。

+0

使用此命令,您将汽车引用设置为空,如果有对同一对象的其他引用他们仍然会指向同一个对象。 – jannagy02

+0

@ jannagy02 - 这就是我在回答中提到的那样做是不可行的。 –

4

我会建议使用.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; 
    } 

    } 
} 

现在在你的代码:

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

为什么在这种情况下调用SupressFinalize?没有什么可以敲定的,即使OP已经定义了Finalizer。 –

+0

@SimonWhitehead谢谢指出。我的坏,我有点懒惰解释的东西。现在更新了整个实施.. –

0

可以proxyfy与你的对象,参考文献,例如字典单身。你可以不存储对象,但可以存储它的ID或散列,并访问它以形成字典。然后,当您需要删除该对象时,您将它的键值设置为null。

4

这听起来像是你需要创建一个围绕一个实例的包装,你可以作废:

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

,你可以用它喜欢:

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

注意然而,如果任何代码保存一个变量的内部值,通过调用Delete不会失效。

1

您不能删除C#中的托管对象。这就是为什么叫做MANAGED语言。所以你不必用删除操作(就像在C++中一样)。

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

那么它是如何完成的呢?因此: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 !!! 
+0

'GC.Collect'收集所有世代..不只是“一代”。 –

+0

@Simon怀特黑德我的赦免。确实是的! –

+0

我认为这是不可能的。我将使用数据库来存储数据而不是实例。因为如果我删除数据库中的数据,所有对数据库中数据的引用都将自动为空,这就是这种愚蠢的语言无法做到的。 我不明白为什么这个简单的事情不能做到,C#知道他在哪里保存他的insatnces,为什么他不能删除它们? – user1576055

3

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

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

-1

您可以使用扩展方法来实现此目的。

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

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

编辑 对不起没有注意到类的方法/所有引用的一部分,但无论如何,我会离开它。

+0

OP没有寻找调用'myCar = null'的奇特方式,但是为了强制所有在系统中持有的实例失效。 –

+0

同样,“删除”不是这个适合的术语。你正在设置对'null'的引用。不删除一个对象。直到垃圾收集器决定删除它,它仍在内存中。那是什么时候被删除。 –

0

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

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

+0

这不提供问题的答案。要批评或要求作者澄清,在他们的帖子下留下评论 - 你总是可以评论你自己的帖子,一旦你有足够的[声誉](http://stackoverflow.com/help/whats-reputation),你会能够[评论任何帖子](http://stackoverflow.com/help/privileges/comment)。 – Jonesopolis

+0

@Jonesopolis我认为这是答案,你为什么不同意? – user3761570

+0

@ Knelis我是新人,不知道你可以把话放在我的嘴里,我很伤心! 另外我认为它必须是参考的参考。 因为你不想让你的收藏空,但所有用户创建的实例。 – user3761570