Khi nào một con hươu cao cổ không phải là một con hươu cao cổ?


23

Tôi hy vọng loại "câu đố" này không có ý nghĩa trong Lập trình Câu đố & Code Golf.

Cho một ví dụ về tình huống trong đó phương thức C # bên dưới trả vềfalse :

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

Quy tắc: Các dòng mã ở trên không được thay đổi theo bất kỳ cách nào, nhưng bạn sẽ đặt mã vào một ứng dụng để "dự án" biên dịch và phương thức được gọi. Khi chạy, phương thức phải trả về false. Giải pháp tôi có trong đầu, không phát ra IL của chính nó vào thời gian chạy hoặc những thứ "kỳ lạ" tương tự, đó là một cuộc gọi phương thức thông thường.


2
Theo "phương thức được gọi", bạn có nghĩa là phải nói rằng Giraffe giraffe = new Giraffe(); giraffe.Test(); phải xảy ra bằng cách nào đó để dòng trong phương thức đó thực tế được thực thi?
Jesse C. Choper

@ JesseC.Slicer Vâng, trong giải pháp tôi có trong đầu, dòng đó xảy ra. Tất nhiên, thật thú vị khi thấy các giải pháp khác mà tôi chưa từng nghĩ đến. Vì vậy, nếu bạn có một cái gì đó, hãy đăng nó!
Jeppe Stig Nielsen

1
Chà, giải pháp đơn giản của tôi trông giống hơn Animal giraffe = new Giraffe(); giraffe.Test();và lớp cha Animalcó một Test()phương thức trả về false. Đó là gian lận một chút khi nó gọi phương thức lớp cha chứ không phải Giraffelà. Nhưng trang web cuộc gọi trông giống nhau.
Jesse C. Choper

@ JesseC.Slicer Ah, tôi hiểu rồi. Tôi sẽ lập luận rằng với "giải pháp" của bạn, đó không phải là "phương pháp dưới đây" (như đã nói trong vấn đề của tôi) mà trả về false, vì vậy tôi sẽ không nói đó là một giải pháp đầy đủ. Nhưng vẫn thú vị. Giải pháp của tôi không có bất kỳ phương pháp ẩn (gợi ý) nào, nhưng như tôi đã nói, các giải pháp khác cũng có thể thú vị.
Jeppe Stig Nielsen

Câu trả lời:


28

Yay, tìm thấy nó!

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

Giraffe 1là thành viên của Animal, và Giraffe 2là một cấp độ nữa, nên tên Giraffetrong isbài kiểm tra đề cập đến cái trước (phần 7.6.2 trong thông số C # 5).

Visual Studio hiển thị cảnh báo cho this is Giraffe:

Biểu thức đã cho không bao giờ thuộc loại được cung cấp

Điều này rõ ràng là đúng, vì đó là toàn bộ vấn đề :)

Bạn không thể đặt Giraffe 1trực tiếp vào bên trong Giraffe 2, bởi vì

tên thành viên không thể giống với kiểu kèm theo của chúng

- nhưng quy tắc như vậy không tồn tại cho các lớp dẫn xuất.

Vấn đề gọn gàng, đưa tôi một thời gian.


11
Chơi tốt thưa ngài
Marc Gravell

2
Vâng, đây là giải pháp tôi có trong tâm trí! Vì vậy, có hai loại, một loại lồng nhau TheNamespace.Animal.Giraffedo thừa kế cũng có thể được gọi TheNamespace.Giraffe.Giraffevà một loại không lồng nhau TheNamespace.Giraffe. Tham chiếu của bạn đến thông số C # có liên quan! Bạn có thể thoát khỏi cảnh báo trình biên dịch. Chỉ cần thay đổi kiểu lồng nhau của lớp cơ sở từ classsang interface. Trong trường hợp đó, một người nào đó có thể xuất phát từ việc không được lồng Giraffe và cũng thực hiện lồng nhau Giraffe, vì vậy trong trường hợp đó, trình biên dịch không thể khiếu nại; đó là một loại kiểm tra "công bằng".
Jeppe Stig Nielsen

1
Tôi không hiểu giải pháp này - đó có thể là vì tôi không biết nhiều về C #. Tôi không thích cái này chơi trên tên. Tôi tìm thấy giải pháp của @ JesseC.Slicer thông minh hơn nhiều.
Nicolas Barbulesco
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.