开发者

Disposing objects - how correctly print base type on the screen

开发者 https://www.devze.com 2023-03-20 03:09 出处:网络
I am following MSDN guideline of implementing a Dispose Method. I\'ve written my simple code to better understand and run the code step by step.

I am following MSDN guideline of implementing a Dispose Method. I've written my simple code to better understand and run the code step by step.

EDITED: changed title to better fit the problem

This is the code:

class Program {
    static void Main(string[] args) {
        Base0 base0 = new Base0();
        base0.Dispose();

        Console.WriteLine();
        Sub1 sub1 = new Sub1();
        sub1.Dispose();

        Console.ReadLine();
    }
}
class Base0 : IDisposable {
    private bool disposed;
    public Base0() {
        Console.WriteLine("Creating Base0!");
        this.disposed = false;
        // allocating some resources
    }
    public void Dispose() {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    protected virtual void Dispose(bool di开发者_StackOverflow社区sposing) {
        Console.WriteLine("Disposing " + this.GetType().ToString() + "!");
        if (!this.disposed) {
            if (disposing) {
                // disposing all managed resources
            }
            // disposing all unmanaged resources
        }
    }
    public void DoSomething() {
        if (this.disposed) {
            throw new ObjectDisposedException(this.GetType().ToString());
        }
    }
    ~Base0() {
        Dispose(false);
    }
}
class Sub1 : Base0 {
    private bool disposed;
    public Sub1() {
        Console.WriteLine("Creating Sub1!");
        this.disposed = false;
        // allocating some resources
    }
    protected override void Dispose(bool disposing) {
        Console.WriteLine("Disposing " + this.GetType().ToString() + "!");
        if (!this.disposed) {
            try {
                if (disposing) {
                    // disposing all managed resources
                }
                // disposing all unmanaged resources
            }
            finally {
                base.Dispose(disposing);
            }
        }
    }
}

This is the output:

Creating Base0!  
Disposing DisposeFinalizeMethods.Base0!  

Creating Base0!  
Creating Sub1!  
Disposing DisposeFinalizeMethods.Sub1!  
Disposing DisposeFinalizeMethods.Sub1!

I am confused because I expected that the last line would be saying "Diposing ... Base0!", the base type.

The code executes as it should, I've checked it 'step by step' many times, I understand it but there is something that I've missed. What am I missing?


OK, this is not about Dispose or IDisposable but about GetType.

this.GetType() is a call to a virtual method. When called in a base-class it will give the Type of the actual (derived) type.

To reproduce:

class A
{
    public virtual void Print()
    {
        Console.Write(this.GetType().Name);
    }
}

class B : A
{
    public override void Print()
    {
        base.Print();
        Console.Write(this.GetType().Name);
    }
}


        var b = new B();
        b.Print();

Will print BB.


You would have to use typeof(Base0) in Base0's Dispose method. GetType always returns the type that was actually instantiated.


As the caller (type that calls) object is of type Sub1 you will see it two times.

This is virtual method so calling on base class GetType will return caller's type

It's correct.


If you want to find out the compile-time type of a parameter, it may be helpful to use the generic method illustrated below:

    static class typeGetter
    {
        static Type getKnownType<T>(this T it) where T : class
        {
            return typeof(T);
        }
        static String test()
        {
            IEnumerable<System.IO.Stream> myThing = new List<System.IO.MemoryStream>();
            return String.Format("Run-time type {0} but compile-time type {1}",myThing.GetType().ToString(),myThing.getKnownType().ToString());
        }
    }

Evaluating test() will yield (line-break added for readability)

"Run-time type System.Collections.Generic.List1[System.IO.MemoryStream] but
  compile-time type System.Collections.Generic.IEnumerable1[System.IO.Stream]"
The getKnownType method will return the compile-time type of the variable or expression that's passed to it, even if the object in question happens to have a more deeply derived type at run-time.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号