2013-10-20 100 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