2010-10-07 28 views
21

Thời gian cho một câu hỏi lý thuyết mà tôi vừa chạy qua.Ghi đè một phần một thuộc tính tự động ảo trong lớp con

Các mã sau đây là hợp lệ và biên dịch:

public class Parent 
{ 
    public virtual object TestProperty { get; set; } 
} 

public class Child : Parent 
{ 
    private string _testValue = "Hello World!"; 

    public override object TestProperty 
    { 
     get { return _testValue; } 
    } 
} 

public class Consumer 
{ 
    Parent p = new Child(); 

    public Consumer(){ p.TestProperty = 3; } 
} 

Câu hỏi của tôi là:

Tại sao C# cho phép tôi một phần ghi đè lên các tài sản TestProperty tự động trong một đứa trẻ khi nó dẫn đến hành vi một phần không thể đoán trước ? Có ứng dụng thực tế nào không?

Tôi được phép đặt giá trị của TestProperty bằng cách sử dụng setter của cha mẹ (tôi đã kiểm tra IL đang được tạo và setter vẫn đặt đối tượng sao lưu trong lớp cha) mặc dù giá trị không thể truy cập công khai.

+1

Câu hỏi thú vị! –

+2

Tôi chắc chắn có rất nhiều điều kỳ lạ như thế này sẽ biên dịch và chức năng, nhưng không có ứng dụng thực tế và tiềm năng tác dụng phụ xấu xí. Hammers xây nhà hoặc đập ngón tay cái tùy thuộc vào cách bạn sử dụng chúng :) –

+2

@Dave - Rất đúng. Tôi chỉ muốn chắc chắn rằng, trong trường hợp này, đập ngón tay cái của tôi với một cái búa không phục vụ một số mục đích mà tôi chỉ không nhìn thấy. –

Trả lời

12

Hành vi này phù hợp với các thuộc tính không được tự động triển khai trong C#. Bạn luôn có thể ghi đè chỉ một phương thức get hoặc set cho một thuộc tính ảo. Do đó làm cho nó không thể làm với một tài sản tự động thực hiện sẽ tạo ra một sự không thống nhất không cần thiết.

Ví dụ, sau đây là hợp pháp

class A 
{ 
    public virtual int P1 
    { 
     get { return 42; } 
     set { } 
    } 
} 

class B : A 
{ 
    public override int P1 
    { 
     get { return 18; } 
    } 
} 
+0

Đủ công bằng. Câu hỏi, sau đó, không giới hạn các thuộc tính tự động. Vẫn còn một chút mờ mặc dù trên các ứng dụng thực tế. Nếu tôi tuyên bố toàn bộ tài sản của mình là một đơn vị duy nhất và đơn vị đó được tạo thành từ một bộ lấy và đặt ... tại sao tôi muốn ghi đè một và rời bỏ một hành vi khác có khả năng gây nhầm lẫn? –

+0

@Justin, Phần nhận và thiết lập của một thuộc tính là các phương thức cơ bản khác nhau nên có nghĩa là chúng có thể được ghi đè độc lập. Về lý do tại sao bạn sẽ muốn có lẽ tôi muốn thêm xác nhận thêm trong hành vi setter hoặc bộ nhớ đệm trong getter nhưng giữ hành vi mặc định cho người khác. Tôi chắc rằng có một số trường hợp sử dụng hợp lệ để thực hiện điều này – JaredPar

+1

@JaredPar - Tôi hiểu rằng chúng là các phương pháp cơ bản khác nhau, nhưng một cách hợp lý cả hai được kết hợp trong tâm trí của tôi. Về thiết kế ngôn ngữ, tuy nhiên, tại sao không yêu cầu ghi đè cả hai và sau đó nếu bạn muốn giữ chức năng hiện tại, bạn chỉ cần gọi hàm return.TestProperty() ;? (có lẽ đây là lý do tại sao tôi không cắt ra để thiết kế ngôn ngữ) –

1

Không nó có ý nghĩa cho một setter, mặc dù? Nếu bạn ghi đè một phần chỉ thiết lập, điều đó có thể hữu ích để bạn có thể trả lời sự kiện đó, ngoài việc gọi số base.TestProperty = value, mà không cần phải bận tâm đến việc ghi đè lên bộ soạn thảo của bộ khởi động.

Các vấn đề liên quan