Утилизация объектов - как правильно печатать базовый тип на экране - PullRequest
1 голос
/ 13 июля 2011

Я следую указаниям MSDN , реализующим метод утилизации .Я написал свой простой код, чтобы лучше понимать и выполнять его шаг за шагом.

EDITED : изменил заголовок, чтобы лучше соответствовать задаче

Это код:

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 disposing) {
        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);
            }
        }
    }
}

Это вывод:

Creating Base0!  
Disposing DisposeFinalizeMethods.Base0!  

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

Я запутался, потому что ожидал, что в последней строке будет написано "Diposing ... Base0!", Базовый тип.

Код выполняется должным образом, я проверял его «шаг за шагом» много раз, я понимаю, но кое-что я пропустил.Чего мне не хватает?

Ответы [ 4 ]

1 голос
/ 13 июля 2011

ОК, речь идет не об утилизации или IDisposable, а о GetType.

this.GetType() - это вызов виртуального метода. При вызове в базовом классе он даст тип фактического (производного) типа.

Воспроизвести:

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();

Распечатает BB.

0 голосов
/ 14 июля 2011

Если вы хотите узнать тип параметра во время компиляции, может быть полезно использовать общий метод, показанный ниже:

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

Оценка test () даст (разрыв строки добавлен для удобства чтения)

"Run-time type System.Collections.Generic.List<code>1[System.IO.MemoryStream] but
  compile-time type System.Collections.Generic.IEnumerable</code>1[System.IO.Stream]"
Метод getKnownType будет возвращать тип времени компиляции для переменной или выражения, переданного ему, даже если у рассматриваемого объекта более глубокий производный тип во время выполнения.
0 голосов
/ 13 июля 2011

Вы должны будете использовать typeof(Base0) в методе удаления Base0. GetType всегда возвращает тип, который был фактически создан.

0 голосов
/ 13 июля 2011

Поскольку объект (вызывающий тип) имеет тип Sub1, вы увидите его два раза.

Это виртуальный метод, поэтому вызов базового класса GetType будетвозвращение вызывающий тип

Это правильно.

...