基於C#中IDisposable與IEnumerable、IEnumerator的應用

來源:互聯網
上載者:User

  C#中如何合理的釋放非託管記憶體?在本文中我們將講解使用IDisposable釋放託管記憶體和非託管記憶體。

  A.首先需要讓類實現IDisposable介面,然後實現IDispose方法。

    A.a核心Disponse(bool isDisponse)

      1.此方法首先判斷isReadyDisposed(判斷是否第一次調用此核心方法),如果不是第一次調用則不做任何操作。

      2.再判斷是否是解構函式調用?如果是解構函式調用不釋放託管資源,其交由GC進行釋放,如果解構函式釋放託管資源可能之前GC釋放過,就會導致出現異常。此判斷內部釋放託管資源記憶體。

      3.釋放非託管資源,並且設定標誌位isReadyDisposed=true.

  B.然後分釋放託管記憶體和非託管記憶體兩種情況進行記憶體釋放處理。

    B.a釋放非託管記憶體

      1.釋放非託管記憶體需要手動調用本類的Dispose()方法,此方法首先調用Dispose(true)手動釋放託管和非託管資源,然後調用GC.SuppressFinalize(this),讓GC不要再調用此對象的解構函式。

    B.b釋放託管記憶體

      1.釋放託管記憶體是由GC自動調用解構函式,解構函式內部調用Dispose(false)方法.此時只釋放非託管資源,而託管資源不管,由GC自行釋放。

  我們實現好的類代碼如下:

複製代碼 代碼如下:public class IDisponseTest : IDisposable
{
private bool isReadyDisposed = false;

~IDisponseTest()
{
//解構函式調用時不釋放託管資源,因為交由GC進行釋放
Disponse(false);
}

public void Dispose()
{
//使用者手動釋放託管資源和非託管資源
Disponse(true);
//使用者已經釋放了託管和非託管資源,所以不需要再調用解構函式
GC.SuppressFinalize(this);

//如果子類繼承此類時,需要按照如下寫法進行。
//try
//{
// Disponse(true);
//}
//finally
//{
// base.Disponse();
//}
}

public virtual void Disponse(bool isDisponse)
{
//isReadyDisposed是控制只有第一次調用Disponse才有效才需要釋放託管和非託管資源
if (isReadyDisposed)
return;
if (isDisponse)
{
//解構函式調用時不釋放託管資源,因為交由GC進行釋放
//如果解構函式釋放託管資源可能之前GC釋放過,就會導致出現異常

//託管資源釋放
}
//非託管資源釋放
isReadyDisposed = true;
}
}

  C#製作一個迭代器對象?使用IEnumerable、IEnumerator

  首先:讓類繼承IEnumerable和IEnumerator介面,此時此類會出現IEnumerable.GetEnumerator()方法和IEnumerator.Current屬性、IEnumerator.MoveNext(),IEnumerator.Reset()方法。

  其次:IEnumerator介面是對象遍曆的方法和屬性實現,而IEnumerable.GetEnumerator()方法是為了擷取IEnumerator對象。

  最後:我們看看迭代器代碼實現如下執行個體:

複製代碼 代碼如下:class Program
{
static void Main(string[] args)
{
CubeEnum cubelist = new CubeEnum(50);
foreach(Cube cube in cubelist)
{
Console.WriteLine("立方體長:" + cube.Length + ",寬" + cube.Width + ",高" + cube.Height);
}
Console.Read();
}
}
//立方體,長、寬、高
public class Cube
{
public int Length { get; set; }
public int Width { get; set; }
public int Height { get; set; }
}
/// <summary>
/// 立方體迭代集合,繼承了IEnumerable和IEnumerator
/// </summary>
public class CubeEnum : IEnumerable, IEnumerator
{
//索引
public int Index { get; set; }
//立方體集合
public Cube[] cubelist { get; set; }
//初始化立方體集合
public CubeEnum(int count)
{
this.Index = -1;
cubelist = new Cube[count];
for (int i = 0; i < count; i++)
{
cubelist[i] = new Cube();
cubelist[i].Length = i * 10;
cubelist[i].Width = i * 10;
cubelist[i].Height = i * 10;
}
}
//實現IEnumerable的 GetEnumerator() 方法獲得IEnumerator對象
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
//當前Cube立方體
public object Current
{
get { return cubelist[Index]; }
}
//往下一步移動
public bool MoveNext()
{
Index++;
if (Index < cubelist.Length)
{
return true;
}
return false;
}
//重設索引
public void Reset()
{
Index = -1;
}
}

本文講述的是C#基礎的應用,如有差錯,敬請斧正。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.