Wann ist eine Giraffe keine Giraffe?


23

Ich hoffe, diese Art von "Rätsel" ist in Programming Puzzles & Code Golf nicht mehr wegzudenken.

Geben Sie ein Beispiel für eine Situation, in der die folgende C # -Methode zurückgibtfalse :

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

Regeln: Die obigen Codezeilen dürfen in keiner Weise geändert werden, aber Sie würden den Code in eine Anwendung einfügen, sodass das "Projekt" kompiliert und die Methode aufgerufen wird. Beim Ausführen muss die Methode zurückgegeben werden false. Die Lösung, die ich vor Augen habe, gibt zur Laufzeit keine eigene IL oder ähnliche "exotische" Dinge aus, es ist ein gewöhnlicher Instanzmethodenaufruf.


2
Meinen Sie mit "die Methode heißt", dass das irgendwie vorkommen Giraffe giraffe = new Giraffe(); giraffe.Test(); muss , damit die Zeile in dieser Methode tatsächlich ausgeführt wird?
Jesse C. Slicer

@ JesseC.Slicer Ja, in der Lösung, die ich vorhabe, kommt diese Zeile vor. Natürlich könnte es interessant sein, andere Lösungen zu sehen, an die ich auch nicht gedacht habe. Also, wenn du etwas hast, poste es!
Jeppe Stig Nielsen

1
Nun, meine einfache Lösung sieht eher so aus Animal giraffe = new Giraffe(); giraffe.Test();und die Elternklasse Animalhat eine Test()Methode, die zurückgibt false. Das ist ein bisschen schummeln, da es eher die übergeordnete Klassenmethode als Giraffe's aufruft . Aber die Anrufseite sieht genauso aus.
Jesse C. Slicer

@ JesseC.Slicer Ah, ich verstehe. Ich würde argumentieren, dass mit Ihrer "Lösung" nicht die "Methode unten" (wie in meinem Problem angegeben) zurückkehrt false, also würde ich nicht sagen, dass es eine vollständige Lösung ist. Aber trotzdem interessant. Meine Lösung hat keine versteckte Methode (Hinweis), aber wie gesagt, andere Lösungen könnten auch interessant sein.
Jeppe Stig Nielsen

Antworten:


28

Ja, gefunden!

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

Da Giraffe 1er Mitglied von Animalund Giraffe 2eine Stufe weiter entfernt ist, bezieht sich der Name Giraffeim isTest auf den ersteren (Abschnitt 7.6.2 in der C # 5-Spezifikation).

Visual Studio zeigt eine Warnung für this is Giraffe:

Der angegebene Ausdruck ist niemals vom angegebenen Typ

Das ist natürlich wahr, da es der springende Punkt ist :)

Sie können nicht Giraffe 1direkt hineinstecken Giraffe 2, weil

Mitgliedsnamen dürfen nicht mit dem umgebenden Typ identisch sein

- Für abgeleitete Klassen gibt es eine solche Regel jedoch nicht.

Ordentliches Problem, dauerte eine Weile.


11
Gut gespielt, Sir
Marc Gravell

2
Ja, das war die Lösung, die ich mir vorgestellt hatte! Es gibt also zwei Typen, einen verschachtelten, TheNamespace.Animal.Giraffeder aufgrund der Vererbung auch aufgerufen werden kann TheNamespace.Giraffe.Giraffe, und einen nicht verschachtelten TheNamespace.Giraffe. Ihr Verweis auf die C # -Spezifikation ist relevant!Sie können die Compiler-Warnung loswerden. Ändern Sie einfach den verschachtelten Typ der Basisklasse von classin interface. In diesem Fall könnte jemand weiter von dem nicht verschachtelten ableiten Giraffe und das verschachtelte ebenfalls implementieren Giraffe, sodass sich der Compiler in diesem Fall nicht beschweren kann. Es ist ein "fairer" Typcheck.
Jeppe Stig Nielsen

1
Ich verstehe diese Lösung nicht - das kann daran liegen, dass ich nicht viel über C # weiß. Ich mag es nicht, mit Namen zu spielen. Ich finde die Lösung von @ JesseC.Slicer viel schlauer.
Nicolas Barbulesco
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.