Когда жираф не жираф?

23

Я надеюсь, что эта "загадка" является онтопом в Программировании Пазлов и Code Golf.

Приведите пример ситуации, когда метод C # ниже возвращаетfalse :

public class Giraffe : Animal
{
  public bool Test()
  {
    return this is Giraffe;
  }
}

Правила: приведенные выше строки кода не должны быть изменены каким-либо образом, но вы должны поместить код в приложение, чтобы «проект» компилировался и вызывался метод. При запуске метод должен вернуться false. Решение, которое я имею в виду, не генерирует свой собственный IL во время выполнения или подобные "экзотические" вещи, это обычный вызов метода экземпляра.

Джепп Стиг Нильсен
источник
2
Под словом «метод вызывается» вы подразумеваете, что это Giraffe giraffe = new Giraffe(); giraffe.Test(); должно произойти как-то так, чтобы строка в этом методе фактически выполнялась?
Джесси С. Slicer
@ JesseC.Slicer Да, в решении, которое я имею в виду, эта строка происходит. Конечно, было бы интересно увидеть и другие решения, о которых я тоже не задумывался. Так что если у вас есть что-то, сделайте это!
Джеппе Стиг Нильсен
1
Ну, мое простое решение больше похоже на то, Animal giraffe = new Giraffe(); giraffe.Test();и у родительского класса Animalесть Test()метод, который возвращает false. Это немного обманывает, поскольку вызывает метод родительского класса, а не Giraffe's'. Но сайт вызова выглядит так же.
Джесси С. Слайсер
@ JesseC.Slicer А, понятно. Я бы сказал, что с вашим «решением» возвращается не «метод ниже» (как сказано в моей проблеме) false, поэтому я бы не сказал, что это было полное решение. Но все же интересно. Мое решение не имеет метода скрытия (подсказка), но, как я уже сказал, другие решения также могут быть интересны.
Джеппе Стиг Нильсен

Ответы:

28

Yay, нашел это!

public class Animal
{
    public class Giraffe { } // 1
}
public class Giraffe : Animal // 2
{
    public bool Test()
    {
        return this is Giraffe;
    }
}

Поскольку он Giraffe 1является членом Animalи Giraffe 2находится на один уровень дальше, имя Giraffeв isтесте относится к первому (раздел 7.6.2 в спецификации C # 5).

Visual Studio показывает предупреждение для this is Giraffe:

Данное выражение никогда не имеет указанного типа

что, очевидно, верно, так как в этом весь смысл :)

Вы не можете положить Giraffe 1прямо внутрь Giraffe 2, потому что

имена членов не могут совпадать с типом включения

- но такого правила не существует для производных классов.

Аккуратная проблема, заняла у меня некоторое время.

balpha
источник
11
Хорошо сыграно, сэр
Марк Грэвелл
2
Да, это было решение, которое я имел в виду! Таким образом, существует два типа: один вложенный, TheNamespace.Animal.Giraffeкоторый также может быть вызван из-за наследования TheNamespace.Giraffe.Giraffe, а другой - не вложенный TheNamespace.Giraffe. Ваша ссылка на спецификацию C # актуальна! Вы можете избавиться от предупреждения компилятора. Просто измените вложенный тип базового класса с classна interface. В этом случае кто-то может получить дальнейшее развитие от не вложенного Giraffe и реализовать также вложенное Giraffe, поэтому в этом случае компилятор не может пожаловаться; это «честная» проверка типов.
Джеппе Стиг Нильсен
1
Я не понимаю это решение - это может быть потому, что я не очень много знаю C #. Мне не нравится играть на именах. Я считаю, что решение @ JesseC.Slicer намного умнее.
Николас Барбулеско