Почему нет циклического наследования с одинаковыми именами базовых и производных классов - PullRequest
3 голосов
/ 19 августа 2011

Просто в другом потоке в SO сегодня я нашел этот небольшой фрагмент кода, который я добавил немного больше, чтобы завершить его,

class GameObject
{
    public virtual void Hello()
    {

        Console.WriteLine("Hello method in base class");
    }
}

class GameObjеct : GameObject 
{
    public override void Hello()
    {
        Console.WriteLine("Hello method in derived class");

    }

}

class Program
{

    public static void Main(string[] args)
    {
        GameObject obj = new GameObject();//Why i never can call Derived? Though c# allows it?
        obj.Hello();


        Console.ReadLine();
    }
}

Теперь, согласно приведенному выше коду, CSC вообще не должен ничего предупреждать. Но код работает на удивление.

Я открыл даже код IL, используя ILDasm, он показывает производный класс, т. Е. GameObject, как имя «GameObject», а имя базового класса без «».

Так что мой вопрос

  1. как компилятор различает эти оба имени класса и даже во время выполнения?

  2. Если наклеить на блокнот с кодировкой ANSI, мы получим странный символ в названии класса с указанием класса, согласно моему другу Абхишеку Сур. http://twitpic.com/68co6z

Спасибо

РЕДАКТИРОВАТЬ: обновление на тот же код с другим именем, я получаю ошибку от компилятора.

class XXXYYY
    {
        public virtual void Hello()
        {

            Console.WriteLine("Hello method in base class");
        }
    }

 class XXXYYY : XXXYYY
    {
        public override void Hello()
        {
            Console.WriteLine("Hello method in derived class");

        }

    }

    class Program
    {

        public static void Main(string[] args)
        {
            XXXYYY obj = new XXXYYY();//Why i never can call Derived? Though c# allows it?
            obj.Hello();


            Console.ReadLine();
        }
    }

Ответы [ 3 ]

8 голосов
/ 19 августа 2011

В основном символ, который выглядит как «e» во втором имени класса, не является символом ASCII. Если вы поместите этот исходный код в текстовый файл с кодировкой, которая его поддерживает (например, UTF-8), и сообщите компилятору C #, какую кодировку использовать (UTF-8 по умолчанию, я считаю), то он будет просматривать их как разные имена классов .

Игнорирование не-ASCII части, это действительно просто класс:

public class Hello {}

public class He11o : Hello {}

В некоторых шрифтах вы можете определить разницу между строчными буквами ell и one, но в некоторых вы не можете. Это разные персонажи.

Когда вы попытались вставить его в блокнот, это не удалось, потому что используемая вами кодировка ANSI (ANSI - неоднозначный термин) не включает этот символ.

РЕДАКТИРОВАТЬ: Ваш второй фрагмент не компилируется по той очевидной причине, что одно и то же имя класса было объявлено дважды. Не два разных имени, которые выглядят одинаково, но на самом деле то же имя .

2 голосов
/ 19 августа 2011

Если я не ошибаюсь e в классе GameObject, который наследует GameObject, это не ASCII e, а скорее специальный символ e.

1 голос
/ 19 августа 2011

Мои баллы:

1.

class GameObject

В IL это GameObject

2.

class GameObject:GameObject

В IL это 'GameObject'

Оба типа отличаются в IL.

3.В Visual Studio IDE, если вы вводите код, e не идентифицируется в GameObject.Следовательно, в исходном файле должен присутствовать некоторый символ ascii, который отличается от двух классов, и когда вы копируете и вставляете, он показывает это точно.

Это означает, что ваши классы различны, и поскольку оба Hello являются виртуальными, ссылка GameObject может вызывать как базовый Hello, так и производный объект, в зависимости от передаваемого вами объекта.

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