SoFunction
Updated on 2025-03-01

Applications based on IDisposable, IEnumerable and IEnumerator in C#

How to reasonably release unmanaged memory in C#? In this article we will explain using IDisposable to release managed and unmanaged memory.

A.First, you need to make the class implement the IDisposable interface, and then implement the IDispose method.

Core Disponse(bool isDisponse)

1. This method first determines isReadyDisposed (judging whether this core method is called for the first time). If it is not the first time, no operation will be done.

2. Then determine whether it isDestructor call? If the destructor call does not release the managed resources, it is handed over to the GC for release. If the destructor releases the managed resources, it may have been released before the GC, which will cause an exception. This judgment releases managed resource memory internally.

3. Release unmanaged resources and set the flag isReadyDisposed=true.

B.Then, the memory release process is divided into two cases: freeing managed memory and unmanaged memory.

Free unmanaged memory

1. Release unmanaged memory requires manually calling the Dispose() method of this class. This method first calls Dispose(true) and manually releases the managed and unmanaged resources, and then calls (this), let GC stop calling the destructor of this object.

Free up managed memory

1. Release managed memory is automatically called by GC, and the destructor internally calls the Dispose(false) method. At this time, only unmanaged resources are released, and regardless of the managed resources, the GC will release them by itself.

Our implementation of the good class code is as follows:

Copy the codeThe code is as follows:

public class IDisponseTest : IDisposable
    {
        private bool isReadyDisposed = false;

        ~IDisponseTest()
        {
//The hosted resources are not released when the destructor is called, because they are handed over to the GC for release.
            Disponse(false);
        }

        public void Dispose()
        {
//Users manually release managed and unmanaged resources
            Disponse(true);
//The user has released managed and unmanaged resources, so there is no need to call the destructor again
            (this);

//If the subclass inherits this class, it needs to be written as follows.
            //try
            //{
            //    Disponse(true);
            //}
            //finally
            //{
            //    ();
            //}
        }

        public virtual void Disponse(bool isDisponse)
        {
//isReadyDisposed controls that only the first call to Disponse is effective, so that managed and unmanaged resources need to be released
            if (isReadyDisposed)
                return;
            if (isDisponse)
            {
//The hosted resources are not released when the destructor is called, because they are handed over to the GC for release.
//If the destructor releases the managed resource, it may have been released before the GC, which will cause an exception

//Housed resources are released
            }
//Unmanaged resources are released
            isReadyDisposed = true;
        }
    }


C# Make an iterator object? Using IEnumerable, IEnumerator

first:Let the class inherit the IEnumerable and IEnumerator interfaces. At this time, this class will have () methods, properties, (), and () methods.

Second:The IEnumerator interface is an implementation of object traversal methods and attributes, and the () method is to obtain the IEnumerator object.

at last:Let's look at the iterator code implementation as follows:

Copy the codeThe code is as follows:

class Program
    {
        static void Main(string[] args)
        {
            CubeEnum cubelist = new CubeEnum(50);
            foreach(Cube cube in cubelist)
            {
("cube length:" + + ",width" + + ",height" +);
            }
            ();
        }
    }
// Cube, length, width, height
    public class Cube
    {
        public int Length { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
    }
    /// <summary>
/// Cube iterative collection, inheriting IEnumerable and IEnumerator
    /// </summary>
    public class CubeEnum : IEnumerable, IEnumerator
    {
//Index
        public int Index { get; set; }
//Cube collection
        public Cube[] cubelist { get; set; }
//Initialize the cube collection
        public CubeEnum(int count)
        {
            = -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;
            }
        }
//Implement the GetEnumerator() method of IEnumerable to obtain the IEnumerator object
        public IEnumerator GetEnumerator()
        {
            return (IEnumerator)this;
        }
//Current Cube
        public object Current
        {
            get { return cubelist[Index]; }
        }
//Move next step
        public bool MoveNext()
        {
            Index++;
            if (Index < )
            {
                return true;
            }
            return false;
        }
//Reset the index
        public void Reset()
        {
            Index = -1;
        }
    }

This article talks about the basic application of C#. If there are any errors, please correct me.