Kapan jerapah bukan jerapah?

23

Saya berharap "teka-teki" semacam ini ontopic di Programming Puzzles & Code Golf.

Berikan contoh situasi di mana metode C # di bawah ini kembalifalse :

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

Aturan: Baris kode di atas tidak boleh diubah dengan cara apa pun, tetapi Anda akan memasukkan kode ke dalam aplikasi sehingga "proyek" dikompilasi dan metode dipanggil. Saat dijalankan, metode harus kembali false. Solusi yang ada dalam pikiran saya, tidak memancarkan IL sendiri pada saat run-time atau hal-hal "eksotis" serupa, itu adalah panggilan metode contoh biasa.

Jeppe Stig Nielsen
sumber
2
Dengan "metode ini disebut", apakah Anda bermaksud mengatakan bahwa itu Giraffe giraffe = new Giraffe(); giraffe.Test(); harus terjadi entah bagaimana sehingga garis dalam metode itu, pada kenyataannya, dieksekusi?
Jesse C. Slicer
@ JesseC.Slicer Ya, dalam solusi yang ada dalam pikiran saya, kalimat itu memang muncul. Tentu saja, mungkin menarik untuk melihat solusi lain yang belum saya pikirkan. Jadi, jika Anda memiliki sesuatu, postinglah!
Jeppe Stig Nielsen
1
Nah, solusi sederhana saya lebih mirip Animal giraffe = new Giraffe(); giraffe.Test();dan kelas induk Animalmemiliki Test()metode yang mengembalikan false. Itu sedikit curang karena memanggil metode kelas induk daripada metode Giraffe. Tetapi situs panggilan terlihat sama.
Jesse C. Slicer
@ JesseC. Irisan Ah, begitu. Saya berpendapat bahwa dengan "solusi" Anda, bukan "metode di bawah" (seperti yang dikatakan dalam masalah saya) yang kembali false, jadi saya tidak akan mengatakan itu adalah solusi lengkap. Tapi tetap menarik. Solusi saya tidak memiliki metode penyembunyian (petunjuk), tetapi seperti yang saya katakan, solusi lain juga bisa menarik.
Jeppe Stig Nielsen

Jawaban:

28

Yay, menemukannya!

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

Karena Giraffe 1merupakan anggota Animal, dan Giraffe 2satu tingkat lebih jauh, nama Giraffedalam istes mengacu pada yang pertama (bagian 7.6.2 dalam spesifikasi C # 5).

Visual Studio menunjukkan peringatan untuk this is Giraffe:

Ungkapan yang diberikan tidak pernah dari jenis yang disediakan

yang jelas benar, karena itu intinya :)

Anda tidak dapat Giraffe 1langsung dimasukkan ke dalam Giraffe 2, karena

nama anggota tidak boleh sama dengan tipe yang dilampirkan

- tetapi aturan seperti itu tidak ada untuk kelas turunan.

Masalah rapi, butuh waktu sebentar.

balpha
sumber
11
Pak, dimainkan dengan baik
Marc Gravell
2
Ya, ini solusi yang ada dalam pikiran saya! Jadi ada dua jenis, satu bersarang TheNamespace.Animal.Giraffeyang karena warisan juga bisa disebut TheNamespace.Giraffe.Giraffe, dan satu non-bersarang TheNamespace.Giraffe. Referensi Anda ke C # spec relevan! Anda bisa menyingkirkan peringatan kompiler. Cukup ganti tipe bersarang dari kelas dasar dari classmenjadi interface. Dalam hal ini seseorang mungkin berasal lebih jauh dari non-bersarang Giraffe dan mengimplementasikan bersarang Giraffejuga, jadi dalam hal itu kompiler tidak dapat mengeluh; ini merupakan pemeriksaan tipe "adil".
Jeppe Stig Nielsen
1
Saya tidak mengerti solusi ini - itu mungkin karena saya tidak tahu banyak C #. Saya tidak suka ini bermain di nama. Saya menemukan solusi dari @ JesseC.Slicer jauh lebih pintar.
Nicolas Barbulesco