Коли жирафа не є жирафом?


23

Я сподіваюсь, що така "загадка" є актуальною у програмуванні головоломки та кодовому гольфі.

Наведіть приклад ситуації, коли метод C # нижче повертаєтьсяfalse :

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

Правила: рядки коду, наведені вище, ні в якому разі не слід змінювати, але ви введете код у додаток, щоб "проект" компілювався і метод викликався. При запуску метод повинен повернутися false. Я маю на увазі рішення, яке не випромінює власну ІЛ під час виконання або подібні "екзотичні" речі, це звичайний виклик методу екземпляра.


2
Під "методом називається", ви хочете сказати, що Giraffe giraffe = new Giraffe(); giraffe.Test(); повинно відбуватися якось так, щоб рядок у цьому методі був насправді виконаний?
Jesse C. Slicer

@ JesseC.Slicer Так, у рішенні, яке я маю на увазі, цей рядок все ж є. Звичайно, може бути цікаво побачити інші рішення, про які я теж не думав. Тож якщо у вас є щось, зробіть це!
Джеппе Стіг Нільсен

1
Ну, моє просте рішення більше схоже, Animal giraffe = new Giraffe(); giraffe.Test();і батьківський клас Animalмає Test()метод, який повертає false. Це трохи обман, як це називає метод батьківського класу, а не Giraffe's. Але сайт дзвінків виглядає так само.
Jesse C. Slicer

@ JesseC.Slicer Ах, бачу. Я б заперечував, що з вашим "рішенням" не повертається "метод нижче" (як сказано в моїй проблемі) false, тому я б не сказав, що це повне рішення. Але цікаво все ж. У моєму рішенні немає жодного методу приховування (підказки), але, як я вже сказав, інші рішення теж можуть бути цікавими.
Jeppe Stig Nielsen

Відповіді:


28

Так, знайшов!

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, тому що

імена членів не можуть бути такими ж, як їх тип, що додається

- але таке правило не існує для похідних класів.

Обережна проблема, зайняла мене час.


11
Добре зіграний сер
Марк Гравелл

2
Так, це було рішення, яке я мав на увазі! Отже, є два типи, один вкладений, TheNamespace.Animal.Giraffeякий через успадкування також можна назвати TheNamespace.Giraffe.Giraffe, і один не вкладений TheNamespace.Giraffe. Ваша посилання на специфікацію C # є актуальною! Ви можете позбутися попередження компілятора. Просто змініть вкладений тип базового класу з classна interface. У такому випадку хтось може вийти далі від вкладеного Giraffe і також вбудувати вкладене Giraffe, тому в цьому випадку компілятор не може скаржитися; це "чесна" перевірка типу.
Jeppe Stig Nielsen

1
Я не розумію цього рішення - це може бути тому, що я не знаю багато C #. Мені не подобається це грати на імена. Я вважаю рішення @ JesseC.Slicer набагато розумнішим.
Ніколя Барбулеско
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.