2009-12-09 19 views
28

thể trùng lặp:
C#: Public Fields versus Automatic PropertiesTại sao có thuộc tính trống được đặt thay vì sử dụng biến thành viên công khai?

Duplicate? Tôi nghĩ rằng không:
Câu hỏi này là không phải là giống như "Tại sao sử dụng các thuộc tính thay vì trường công khai ". Một tài sản có chỉ định getter và setter khác xa hơn trường công khai. Câu hỏi của tôi là, là tài sản KHÔNG CÓ bộ dựng getter và setter, bất kỳ khác biệt nào.

Với khả năng gần đây có các getters và setters trống, lợi ích của việc sử dụng chúng thay vì chỉ khai báo biến thành viên công khai là gì?

Ví dụ:

public string MyProperty 
{ 
    get; 
    set; 
} 

so:

public string MyProperty; 
+10

Đây là một bản sao khá thẳng đứng của http://stackoverflow.com/questions/1180860/c-public-fields-versus-automatic-properties và về cơ bản là bản sao của rất nhiều "Tại sao tôi nên sử dụng các thuộc tính thay vì lĩnh vực công cộng? " câu hỏi. –

+1

Câu hỏi này không giống như "Tại sao sử dụng các thuộc tính thay vì trường công cộng". Một thuộc tính với một getter và setter được chỉ định khác xa so với một trường công khai. Câu hỏi của tôi là, là một tài sản KHÔNG CÓ getter và setter, bất kỳ khác nhau. – Jeremy

+0

Một tài sản mà không có một getter và setter không phải là một tài sản, đó là một lĩnh vực. –

Trả lời

42

Một từ: thừa kế.

Thuộc tính có thể kế thừa trong khi các trường không có. Bạn có thể sử dụng các trường trong một lớp kế thừa, nhưng không thay đổi hành vi của chúng bằng cách làm cho chúng trở nên ảo.

Giống như vậy:

public class Foo { 
    public virtual int MyField = 1; // Nope, this can't 

    public virtual int Bar {get; set; } 
} 

public class MyDerive : Foo { 
    public override MyField; // Nope, this can't 

    public override int Bar { 
    get { 
     //do something; 
    } 
    set; } 
} 

Edit: Bên cạnh thực tế của thừa kế, những điểm đã chỉ ra trong câu trả lời khác (như tầm nhìn) cũng là một lợi ích rất lớn tài sản trên các lĩnh vực.

+6

Trong bối cảnh nào các trường công khai không được thừa kế bởi một lớp dẫn xuất? Hay tôi hiểu lầm bạn? –

+2

Bạn có thể biến chúng thành ảo và ghi đè chúng trong các lớp dẫn xuất. –

+0

Điều gì đó khiến tôi sợ hãi. Nó có vẻ kỳ quặc để được ghi đè một thuộc tính tự động. Kể từ dưới mui xe khuôn khổ là quay lên một thành viên tư nhân để thực sự lưu trữ giá trị của tài sản có vẻ như là bằng cách ghi đè nó, bạn có thể làm điều gì đó bất ngờ. Tôi muốn có khuynh hướng đánh dấu autoproperties như không overrideable. Tôi không thể đặt ngón tay lên đó, nhưng có vẻ như ... kỳ quặc. –

27

Một điều bạn có thể làm với tài sản mà bạn không thể làm với các lĩnh vực là tầm nhìn hạn hoặc setter hoặc getter:

public string MyProperty { get; private set; } 

Something tôi sử dụng khá nhiều.

Và thứ gì đó (mạnh hơn) bạn không thể làm với các trường là xác định chúng bên trong một giao diện. Giả sử bạn muốn một giao diện yêu cầu triển khai các lớp học để có một thuộc tính nhất định:

public interface MyInterface 
{ 
    string MyProperty { get; } 
} 

Lưu ý rằng bạn không cần phải thiết lập ở đây. Hoàn toàn tùy thuộc vào việc triển khai các lớp học để xác định cách họ nên đặt MyProperty.

+0

Bạn đánh bại tôi :-). Có các công cụ sửa đổi truy cập riêng biệt ngay cả khi việc triển khai trống. – SKG

+2

Có thể đáng để chỉ ra rằng bạn có thể làm điều gì đó tương tự (mặc dù không phải là một nửa là mạnh mẽ) bằng cách tuyên bố trường của bạn là chỉ đọc, bằng cách làm điều đó nó chỉ có thể được chỉ định vào lúc xây dựng. –

10

Các trường không thể hiển thị trong giao diện. Và thuộc tính tự động có thể được thay đổi thành thuộc tính "bình thường" bất kỳ lúc nào nếu cần, không có chữ ký và giao diện của lớp đang thay đổi.

Nói chung, các trường được coi là chi tiết triển khai, có thể thay đổi trong các phiên bản sau của mã. Vì vậy, bạn nên phơi bày dữ liệu thông qua các phương thức và thuộc tính, để lại cách mở cho những thay đổi nội bộ trong tương lai mà không ảnh hưởng đến mã sử dụng lớp.

+2

Câu trả lời hay, để làm rõ: việc thay đổi một trường thành một thuộc tính thực sự là một thay đổi phá vỡ vì nó không bảo toàn tính tương thích nhị phân.Một ví dụ sẽ là một số người dùng của lớp có thể làm một số sự phản ánh khi nó và một FieldInfo là một cái gì đó hoàn toàn khác với một PropertyInfo. Ví dụ khác được đề cập trong các câu trả lời khác. –

+0

Cảm ơn bạn đã làm rõ, đó là những gì tôi muốn nói. ;) – Lucero

1

Ý tưởng là quản lý các giá trị bên trong đối tượng, trạng thái, tránh tham nhũng và lạm dụng bằng cách gọi mã.

5

Một tài sản mang đến cho bạn nhiều lợi thế hơn một lĩnh vực công cộng đơn giản:

  • bạn có thể kiểm soát xem bất động sản là chỉ đọc, viết-chỉ, hoặc đọc/viết
  • bạn có thể ẩn thực hiện thực tế (có thể trong setter bạn muốn làm nhiều hơn là chỉ đặt một giá trị)
  • khi sử dụng liên kết dữ liệu (ví dụ như trong ASP.NET), bạn sẽ phải sử dụng tài sản (không hoạt động với các lĩnh vực)
0

Y Bạn có thể gắn cờ các thuộc tính với các thuộc tính không có sẵn trên các thành viên. Có các thuộc tính chỉ áp dụng cho các trường trong không gian tên DataContract ảnh hưởng đến việc tuần tự hóa, không thể áp dụng thuộc tính cho các trường, v.v.

Phải thừa nhận rằng không có bất kỳ điều gì ngăn cản các thuộc tính này được sử dụng trên thành viên, nhưng tuy nhiên chúng chỉ hoạt động trên các thuộc tính.

5

Khớp nối chặt chẽ sẽ xuất hiện trong đầu bạn. Sử dụng các trường công khai loại bỏ lớp trừu tượng được tạo sẵn bằng cách sử dụng các thuộc tính. Việc sử dụng các trường và thuộc tính riêng ẩn đi việc thực hiện từ các lớp khác và giúp cách ly chúng (các lớp bên ngoài) bất cứ khi nào cần thay đổi.

Ngoài ra, hãy nhớ rằng bạn đang đề cập đến auto-implemented properties khiến trình biên dịch tạo trường sao lưu cho bạn thay vì bạn phải tạo trường sao lưu (riêng) theo cách thủ công cho mỗi thuộc tính trên lớp của bạn.

+3

Có. Ẩn bí mật của bạn! –

+0

Hahahaha - không bao giờ nghe theo cách đó :) Tuyệt vời! +1 từ tôi. –

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