ยีราฟจะไม่เป็นยีราฟเมื่อไหร่?


23

ฉันหวังว่า "ปัญหาลับสมอง" แบบนี้เป็นเรื่องเกี่ยวกับการเขียนโปรแกรมปริศนาและโค้ดกอล์ฟ

ยกตัวอย่างสถานการณ์ที่เมธอด C # ด้านล่างส่งคืนfalse :

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

กฎ: บรรทัดโค้ดข้างต้นจะต้องไม่เปลี่ยนแปลง แต่อย่างใด แต่คุณจะต้องใส่รหัสลงในแอปพลิเคชันเพื่อให้คอมไพล์ "project" และวิธีการนั้นถูกเรียก falseเมื่อเรียกใช้วิธีการที่จะต้องกลับ วิธีแก้ปัญหาที่ฉันมีอยู่ในใจไม่ปล่อย IL ของตัวเองในเวลาทำงานหรือสิ่งที่ "แปลกใหม่" ที่คล้ายกันมันเป็นวิธีการแบบปกติที่เรียก


2
โดย "วิธีการที่เรียกว่า" คุณหมายถึงว่าGiraffe giraffe = new Giraffe(); giraffe.Test(); จะต้องเกิดขึ้นอย่างใดเพื่อให้สายในวิธีการที่เป็นจริงในการดำเนินการ?
Jesse C. Slicer

@ JesseC.Slicer ใช่ในการแก้ปัญหาที่ฉันมีอยู่ในใจบรรทัดนั้นจะเกิดขึ้น แน่นอนมันน่าสนใจที่จะเห็นวิธีแก้ไขปัญหาอื่น ๆ ที่ฉันไม่ได้คิดด้วย ดังนั้นถ้าคุณมีบางอย่างทำโพสต์มัน!
Jeppe Stig Nielsen

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
ท่านเล่นได้ดี
Marc Gravell

2
ใช่นี่คือทางออกที่ฉันมีอยู่ในใจ! ดังนั้นจึงมีสองประเภทหนึ่งที่ซ้อนกันTheNamespace.Animal.Giraffeซึ่งเพราะมรดกยังสามารถเรียกว่า และหนึ่งที่ไม่ซ้อนกันTheNamespace.Giraffe.Giraffe TheNamespace.Giraffeการอ้างอิงถึงข้อกำหนด C # นั้นมีความเกี่ยวข้อง! คุณสามารถกำจัดคำเตือนของคอมไพเลอร์ เพียงแค่เปลี่ยนชนิดซ้อนกันของชั้นฐานจากไปclass interfaceในกรณีนั้นบางคนอาจได้รับเพิ่มเติมจากที่ไม่ซ้อนกันGiraffe และใช้ซ้อนกันGiraffeเช่นกันดังนั้นในกรณีนั้นคอมไพเลอร์ไม่สามารถบ่นได้ เป็นการตรวจสอบประเภท "ยุติธรรม"
Jeppe Stig Nielsen

1
ฉันไม่เข้าใจวิธีแก้ปัญหานี้ - อาจเป็นเพราะฉันไม่รู้ C # มาก ฉันไม่ชอบการเล่นตามชื่อ ฉันพบวิธีแก้ปัญหาของ @ JesseC.Slicer ที่ฉลาดกว่ามาก
Nicolas Barbulesco
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.