2014-04-16 13 views
73

Cho đến bây giờ, tôi đã có ấn tượng rằng Properties & Methods là hai điều khác nhau trong C#. Nhưng sau đó tôi đã làm một cái gì đó như dưới đây.Thuộc tính C# có thực sự là Phương pháp không?

enter image description here

và đây là "Eye Opener" cho tôi. Tôi đã mong đợi một tài sản stringProp và một phương thức stringProp nhưng thay vào đó tôi có được điều này.

Tại sao điều này xảy ra? ai đó có thể giải thích xin vui lòng.

+4

Nó không thực sự rõ ràng những gì bạn đang tìm kiếm như một câu trả lời. Nhưng [Properties] (http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx) nói: "... chúng thực sự là những phương thức đặc biệt được gọi là accessors." –

+3

http://en.wikipedia.org/wiki/Syntactic_sugar – ComethTheNerd

+30

Nó không hợp pháp để có một tài sản và phương pháp có cùng tên, vì vậy tôi không ngạc nhiên Intellisense là nhầm lẫn. –

Trả lời

104

Có, trình biên dịch tạo ra một cặp phương thức nhận và đặt cho thuộc tính, cộng với trường sao lưu riêng cho thuộc tính được tự động triển khai.

public int Age {get; set;} 

trở nên tương đương với:

private int <Age>k__BackingField; 

public int get_Age() 
{ 
    return <Age>k__BackingField; 
} 

public void set_Age(int age) 
{ 
    <Age>k__BackingField = age; 
} 

Mã mà truy cập vào tài sản của bạn sẽ được biên dịch để gọi một trong hai phương pháp này. Đây chính xác là một trong những lý do tại sao việc thay đổi một lĩnh vực công khai thành tài sản công cộng là một thay đổi đột phá.

Xem Jon Skeet Why Properties Matter.

+10

Thật kỳ lạ, '' trong mã là gì? – ca9163d9

+29

@ dc7a9163d9 Trên thực tế, ' k__BackingField' là tên của trường. Mặc dù đó là một tên bất hợp pháp trong C#, đó là một tên hoàn toàn hợp lệ trong IL (Intermediate Language). Đây là IL được tạo ra để khai báo trường đó: '. Private private int32 ' k__BackingField''. Hầu hết các loại trình biên dịch tạo ra, chẳng hạn như đóng cửa lambda và liệt kê chứa '<>' trong tên của chúng. – dcastro

16

Đây là vấn đề quan sát trực quan trong studio trực quan, chọn theo tên. Bằng cách mã của bạn sẽ không biên dịch ngay cả, do tên va chạm trong cùng một loại.

Nhưng bạn là đúng, rằng tài sản phương ở cuối:

public class A { 

    public string Name {get;set;} 
} 

đây Name tài sản được chuyển thành 2 phương pháp: get_Name()set_Name().

Trong thực tế, nếu bạn định nghĩa lớp như thế này:

public class A { 

    public string Name {get;set;} 

    public string get_Name() { 
     return "aaa"; 
    } 
} 

bạn sẽ nhận được lỗi biên dịch, vì có đã được xác định get_Name (tài sản)

24

Nói đúng ra, tài sản không phải là phương pháp, mặc dù họ thực sự được hỗ trợ bởi các phương thức getter và setter (còn gọi là accessors). Khi bạn viết mã như thế này (với điều kiện bạn thay đổi mã để loại bỏ các lỗi biên dịch đề cập dưới đây)

myFoo.stringProp = "bar"; 

Trình biên dịch thực sự tạo ra mã IL như thế này:

ldstr  "bar" 
callvirt foo.set_stringProp 

đâu set_stringProp là phương pháp setter cho tài sản đó. Trong thực tế, nếu bạn muốn, bạn có thể gọi trực tiếp các phương thức này thông qua sự phản chiếu.

Tuy nhiên, mẫu mã bạn đã đăng có thể trông ổn trong IntelliSense của Visual Studio, nhưng nó sẽ không biên dịch.Cố gắng xây dựng dự án và bạn sẽ thấy một lỗi như:

Loại 'foo' đã có chứa một định nghĩa cho 'stringProp'

+2

Sự khác biệt lớn nhất là các thuộc tính có thể có siêu dữ liệu được liên kết bổ sung thông qua các thuộc tính có thể không áp dụng cho các phương pháp. –

-1

Yes. Thuộc tính là mutator phương pháp.

Trong khoa học máy tính, phương pháp trình biến đổi là phương pháp được sử dụng để kiểm soát các thay đổi đối với biến. Chúng cũng được biết đến rộng rãi như các phương thức setter. Thường thì một setter được đi kèm với một getter (còn được gọi là accessor), trả về giá trị của biến thành viên riêng.

Phương pháp biến tần thường được sử dụng nhất trong lập trình hướng đối tượng, phù hợp với nguyên tắc đóng gói. Theo nguyên tắc này, các biến thành viên của một lớp được đặt riêng để ẩn và bảo vệ chúng khỏi mã khác, và chỉ có thể được sửa đổi bởi hàm thành viên công cộng (phương thức mutator), lấy giá trị mới mong muốn làm tham số, xác nhận tùy chọn nó, và sửa đổi biến thành viên riêng.

Phương pháp đột biến cũng có thể được sử dụng trong môi trường không hướng đối tượng. Trong trường hợp này, một tham chiếu đến biến được sửa đổi được chuyển tới trình biến đổi, cùng với giá trị mới. Trong trường hợp này, trình biên dịch không thể hạn chế mã từ bỏ qua phương thức mutator và thay đổi biến trực tiếp. Các onus rơi vào các nhà phát triển để đảm bảo biến chỉ được sửa đổi thông qua các phương pháp mutator và không sửa đổi trực tiếp.

Trong các ngôn ngữ lập trình có hỗ trợ chúng, các thuộc tính cung cấp giải pháp thay thế tiện lợi mà không từ bỏ tiện ích đóng gói.

Tham chiếu: http://en.wikipedia.org/wiki/Mutator_method

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