Как избежать изменения класса при назначении объекта производного класса для объекта базового класса в C # 4? - PullRequest
0 голосов
/ 19 февраля 2011

Привет из C # и новичок ООП.

Как можно избежать изменения класса при назначении объекта производного класса объекту базового класса в c #?После запуска приведенного ниже кода я получаю этот ответ

obj1 - TestingField.Two
obj2 - TestingField.Two

Я ожидал, что потеряю доступ к производным методами свойства (что я и сделал) после назначения ссылки, но я не ожидал изменения класса в мидкоде: S

using System;

namespace TestingField
{
    class Program
    {
        static void Main(string[] args)
        {
            One obj1 = new One();
            Two obj2 = new Two();
            obj1 = obj2;
            Console.WriteLine("obj1 is {0}", obj1.GetType());
            Console.WriteLine("obj2 is {0}", obj2.GetType());
            Console.ReadLine();
        }
    }

    class One
    {
    }

    class Two : One
    {
        public void DoSomething()
        {
            Console.WriteLine("Did Something.");
        }

    }
}

Ответы [ 3 ]

1 голос
/ 19 февраля 2011

Хотя вы правы, вы потеряете доступ к элементам , объявленным в производном типе, объект не изменит внезапно свой тип или реализацию . Вы можете получить доступ только к членам, объявленным в базовом типе, но реализация производного типа используется в случае переопределенных членов, что имеет место с GetType, который является методом, сгенерированным компилятором, который автоматически переопределяет реализацию базового класса.

Расширение вашего примера:

class One
{
   public virtual void SayHello()
   {
      Console.WriteLine("Hello from Base");
   }
}

class Two : One
{
    public void DoSomething()
    {
        Console.WriteLine("Did Something.");
    }
    public override void SayHello()
    {
      Console.WriteLine("Hello from Derived");
    }

}

Дано:

One obj = new Two();
obj.SayHello(); // will return "Hello from Derived"
1 голос
/ 19 февраля 2011

GetType - это виртуальный метод, который дает вам динамический тип объекта.

Я думаю, вы хотите статический тип переменной. Вы не можете получить это, вызвав метод объекта, на который ссылается переменная. Вместо этого просто напишите typeof(TypeName), что в вашем случае равно typeof(One) или typeof(Two).

В качестве альтернативы в вашем подклассе вы можете использовать новый метод, который скрывает оригинальный вместо того, чтобы переопределять его:

class One
{
    public string MyGetType() { return "One";  }
}

class Two : One
{
    public new string MyGetType() { return "Two"; }
}

class Program
{
    private void Run()
    {
        One obj1 = new One();
        Two obj2 = new Two();
        obj1 = obj2;

        Console.WriteLine("obj1.GetType(): " + obj1.GetType());
        Console.WriteLine("obj2.GetType(): " + obj2.GetType());
        Console.WriteLine("obj1.MyGetType(): " + obj1.MyGetType());
        Console.WriteLine("obj2.MyGetType(): " + obj2.MyGetType());
    }
}

Результат:

obj1.GetType(): Two
obj2.GetType(): Two
obj1.MyGetType(): One
obj2.MyGetType(): Two
0 голосов
/ 19 февраля 2011

Вы не «изменили класс». Тип переменной obj1 по-прежнему One. Вы присвоили экземпляр Two этой переменной, что разрешено, поскольку Two наследуется от One. Метод GetType дает вам фактический тип объекта, на который в данный момент ссылается эта переменная, а не тип самой объявленной переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...