2009-10-06 45 views
12

Bạn có thể cho tôi biết cách sử dụng chính xác của tài sản trong C# tôi có nghĩa là lời giải thích thực tếTại sao chúng ta cần Properties trong C#

trong dự án của chúng tôi, chúng tôi đang sử dụng tài sản như

/// <summary> 
/// column order 
/// </summary> 
protected int m_order; 

/// <summary> 
/// Get/Set column order 
/// </summary> 
public int Order 
{ 
    get { return m_order; } 
    set { m_order = value; } 
} 

/// <summary> 
/// constructor 
/// </summary> 
/// <param name="name">column name</param> 
/// <param name="width">column width</param> 
/// <param name="order">column order</param> 
public ViewColumn(string name, int width, int order) 
{ 
    // 
    // TODO: Add constructor logic here 
    // 
    m_name = name; 
    m_width = width; 
    m_order = order; 
} 


/// <summary> 
/// returns the column name, width, and order in list view. 
/// </summary> 
/// <returns>string represent of the ViewColumn object</returns> 
public override string ToString() 
{ 
    return (string.Format("column name = {0}, width = {1}, order = {2}.", 
     m_name, m_width, m_order)); 
} 

/// <summary> 
/// Do a comparison of 2 ViewColumn object to see if they're identical. 
/// </summary> 
/// <param name="vc">ViewColumn object for comparison</param> 
/// <returns>True if the objects are identical, False otherwise.</returns> 
public override bool Equals(object obj) 
{ 
    ViewColumn vc = (ViewColumn)obj; 
    if(m_name == vc.Name && 
     m_width == vc.Width && 
     m_order == vc.Order) 
     return true; 
    else 
     return false; 
} 
+0

của [Tôi có nên sử dụng các thuộc tính công khai và các trường riêng tư hoặc các trường công khai cho dữ liệu không?] (http://stackoverflow.com/questions/1277572/should-i-use-public-properties-and-private-fields-or-public- các trường dữ liệu) – nawfal

Trả lời

16

Hãy suy nghĩ về nó: Bạn có một phòng khách và một cánh cửa để vào căn phòng này. Nếu bạn muốn kiểm tra xem ai sẽ đến và bảo vệ phòng của bạn, thì bạn nên sử dụng tài sản nếu không họ sẽ không có bất kỳ cánh cửa nào và mọi người dễ dàng đến với bất kỳ quy định nào.

class Room { 
    public string sectionOne; 
    public string sectionTwo; 
} 

Room r = new Room(); 
r.sectionOne = "enter"; 

Mọi người đang truy cập phầnMột cách dễ dàng, không có bất kỳ kiểm tra nào.

class Room 
{ 
    private string sectionOne; 
    private string sectionTwo; 

    public string SectionOne 
    { 
     get 
     { 
     return sectionOne; 
     } 
     set 
     { 
     sectionOne = Check(value); 
     } 
    } 
} 

Room r = new Room(); 
r.SectionOne = "enter"; 

bây giờ bạn đã kiểm tra người đó và biết liệu anh ấy có điều gì đó ác với anh ấy không.

+0

Đẹp .. Hãy giữ nó lên –

31

Câu trả lời ngắn là gì: Đóng gói

Câu trả lời dài: Các thuộc tính rất linh hoạt. Nó cho phép bạn chọn cách bạn muốn hiển thị dữ liệu của mình cho các đối tượng bên ngoài. Bạn có thể tiêm một số lượng xác thực dữ liệu khi thiết lập các giá trị. Nó cũng làm tăng thêm sự đau đầu của các phương thức getX()setX() được thấy trong Java, v.v.

+9

Trả lời ngắn: để làm cho mẫu getX()/setX() đẹp hơn. Câu trả lời dài: Đóng gói. [cần dẫn nguồn];) – Jimmy

+1

ví dụ: xem http://stackoverflow.com/questions/1461598/what-is-the-point-of-setters-and-getters-in-java – Jimmy

+0

+1 cho câu trả lời -1 cho câu hỏi: Tại sao câu trả lời này không được chấp nhận? –

0

Chúng hữu ích cho việc ràng buộc dữ liệu.

4

Đó là cách để sử dụng nó, ngoại trừ cách bạn đang thiết lập nó, có thể. Thay vì truy cập vào biến thành viên, bạn có thể muốn sử dụng thuộc tính từ bên trong lớp, vì vậy bạn có thể sử dụng các quy tắc thống nhất về từng biến thành viên. Đây là lợi thế chính để sử dụng các thuộc tính, là mang lại truy cập và logic setter thành một nơi. Nó thực sự phụ thuộc vào nhu cầu cụ thể của bạn cho dù bạn có muốn thiết lập nó bằng cách sử dụng tài sản hay không. Tuy nhiên, lưu ý rằng trong hàm dựng bạn muốn rất cẩn thận khi gọi thuộc tính, vì bạn có thể hoặc không thể dựa vào các phần khác của lớp đang được khởi tạo mà sẽ không được thực hiện nếu truy cập thông qua hàm tạo. Một lần nữa, điều này phụ thuộc vào việc triển khai cụ thể của bạn.

Nó cũng là một chút bụi để sử dụng:

myObject.Property1 = "Test String"; 
Console.WriteLine(myObject.Property1); 

hơn những gì bạn thấy trong một số ngôn ngữ khác:

myObject.setProperty1("Test String"); 
System.out.writeln(myObject.getProperty1()); 

Dưới đây là một trường hợp mà bạn có thể tóm lược một số logic:

public int Order 
{ 
    get { return m_order; } 
    set 
    { 
     // Put some rules checking here. Maybe a call to make sure that the order isn't duplicated or some other error based on your business rules. 
     m_order = value; 
    } 
} 

Một cách khác chúng hữu ích sẽ như sau:

public int Order { get; private set; } 

Và bây giờ bạn đã có thuộc tính được tự động triển khai với biến thành viên sao lưu chỉ có thể được đặt bên trong lớp nhưng đọc ở mọi nơi khác.

Cuối cùng, nếu bạn cần phải kiểm soát logic, bạn có thể viết này:

public int Order 
{ 
    get { return m_order; } 
    protected set 
    { 
     // Again, you can do some checking here if you want... 
     m_order = value; 
     // You can also do other updates if necessary. Perhaps a database update... 
    } 
} 
+0

bạn có thể cho tôi một lời giải thích thực tế với mã số – peter

+0

Có bạn đi, tôi đã thêm một số. – jasonh

16

Rất nhiều lý do:

  • Semantics. Các thuộc tính tách riêng việc triển khai loại của bạn khỏi giao diện.
  • Khả năng tương thích nhị phân. Nếu bạn cần thay đổi thuộc tính, bạn có thể làm như vậy mà không phá vỡ tính tương thích nhị phân cho mã phụ thuộc. Với các trường, bạn phải biên dịch lại mọi thứ ngay cả khi triển khai mới sử dụng thuộc tính có cùng tên.
  • Databinding. Bạn không thể databind vào một trường.
+3

Bạn đã bao giờ ngủ chưa? –

+0

* Bitch tát bản thân mình * Tôi không biết rằng điều tương thích nhị phân. Tốt đẹp. – Tarik

+0

@Justin: chỉ vào những ngày kết thúc bằng 'y', nhưng đôi khi không lâu. –

3

Như Justin đã lưu ý, đóng gói là một trong các nguyên lý cơ bản của OOP. Bạn sẽ muốn giữ biểu diễn nội bộ của dữ liệu trong lớp của bạn được ẩn từ bên ngoài và cung cấp các cách duyệt/thao tác nó đã được phê duyệt.

Thuộc tính C# là các cấu trúc cung cấp cách dễ dàng để thực hiện điều đó. Trong ví dụ của bạn, bạn không làm bất cứ điều gì bên trong getset phương pháp nhưng trong cuộc sống thực bạn có thể cần phải làm những việc nhất định như

  • tệ Store trong ngày 10 cent như một số nguyên dài nhưng trở lại với thế giới bên ngoài dưới dạng chuỗi có 2 dấu cách thập phân và ký hiệu $.
  • Hạn chế một thuộc tính nhất định là chỉ đọc (hoặc thậm chí chỉ ghi: đối với ví dụ :, trình xác thực mật khẩu/lớp trình tạo băm).
  • Thay đổi trạng thái của đối tượng bằng cách nào đó khi giá trị này được đặt/nhận.

Trong Java, bạn viết getters và setters là các phương thức thuần cũ trả lại hoặc chấp nhận giá trị tương ứng.

+0

+1 cho khía cạnh bộ định hướng truy cập để điều chỉnh không chỉ ở cấp dữ liệu (như thành viên) mà còn cấp độ hoạt động (get/set): chỉ đọc, chỉ ghi – jdehaan

+0

. . Trong thực tế, trình biên dịch C# tạo các phương thức như get_Order và set_Order cho thuộc tính và sẽ không cho phép bạn định nghĩa phương thức của riêng mình với cùng tên. – softveda

6

Dưới đây là một mô hình phổ biến:

class Foo { 

    private Bar _bar; 

    //here, Foo has a Bar object. If that object has already been instantiated, return that value. Otherwise, get it from the database. 
    public Bar bar { 
     set { _bar = value;} 
     get { 
      if (_bar == null) { 
       _bar = Bar.find_by_foo_name(this._name); 
      } 
      return _bar; 
     } 
    } 
} 

Nói tóm lại, điều này cho phép chúng ta truy cập vào đối tượng Bar trên ví dụ của chúng ta về Foo. Sự đóng gói này có nghĩa là chúng ta không phải lo lắng về cách Bar được lấy ra, hoặc nếu foo.bar đã được khởi tạo. Chúng tôi chỉ có thể sử dụng các đối tượng và để cho các internals của lớp Foo chăm sóc nó.

4

Thuộc tính được sử dụng để hạn chế quyền truy cập trực tiếp vào các biến thành viên của một lớp. Trừu tượng được duy trì bằng cách sử dụng các thuộc tính. Bất cứ khi nào bạn muốn khởi tạo một đối tượng và đặt dữ liệu cho các biến thành viên của nó bằng cách sử dụng thuộc tính, bạn có thể kiểm tra một số điều kiện liệu giá trị đó có được đặt thành biến thành viên hay không. Bạn có thể hạn chế đọc ghi vào một thuộc tính sao cho giá trị của biến thành viên có thể chỉ đọc, viết trong khi truy cập đối tượng của lớp đó.

4

Thiết kế Thời gian Lợi ích

Thuộc tính làm cho hình ảnh thiết kế dễ dàng, bạn có nổi tiếng nhất của trình duyệt tài sản của Visual Studio cho phép bạn thay đổi thuộc tính của đối tượng.

Thuộc tính cũng cung cấp metadata bổ sung xác nhận, xuất hiện hình ảnh bên trong trình duyệt tài sản, như thả xuống, phạm vi, chọn màu sắc vv

tách dữ liệu và hành động

Họ thật sự đại diện cho sự khác biệt giữa "dữ liệu" đối tượng và "Hành động" (Phương thức) của đối tượng.

Khi chúng ta xem xét lớp học, nếu chúng ta có 50 phương pháp để xem xét, không phải ai cũng sẽ sử dụng đúng cách đặt tên hàm, điều đó sẽ làm cho mọi thứ khó hiểu sau này.Tôi luôn nói với các lập trình viên rằng bất cứ khi nào bạn lập trình, hãy viết mã theo cách mà sau 5 năm, nếu ai đó nhìn vào mã, anh ta nên hiểu mã.

Sử dụng tên phương thức truy cập dữ liệu và một số hành động gây nhầm lẫn về lâu dài ... như trong trường hợp Stack, Push/Pop là các hành động nhưng "Kích thước" hoặc "Đếm" là dữ liệu.

Tạo thuộc tính "Đếm" chỉ đơn giản là phân biệt mục đích của nó dưới dạng dữ liệu thay vì hành động.

Databinding

Như đã đề cập bởi những người khác, tính chất cung cấp độ tiên tiến của liên kết dữ liệu giống như hai cách ràng buộc, vv

Hạn chế truy cập

Bạn có thể có thuộc tính chỉ đọc và accessors thêm như đã đề cập bởi những người khác.

Reflection

nó chút dễ dàng để làm việc với các tài sản trong trường hợp viết mã chung dựa trên sự phản xạ.

lưu trữ khác nhau thực hiện

biến công cộng lưu trữ dữ liệu chỉ như là các thành viên, trong đó đặc tính khác cung cấp nhiều cách để lưu trữ dữ liệu trong các hình thức khác nhau như internaly họ có thể được lưu trữ như Hashtable (như chúng được thực hiện trong các đối tượng phụ thuộc vào WPF). Chúng có thể được lưu trữ. Họ cab được chuyển tiếp đến một số thực thể con khác hoặc các thực thể nhận thức. Tuy nhiên việc triển khai được ẩn cho người gọi.

Validation

tài sản Thiết có thể yêu cầu xác nhận nào đó, và mã xác nhận trong "Thiết lập" một phần của mã có thể dễ dàng giúp bạn xác thực đầu vào và báo cáo lỗi cho phù hợp.

Notifications

Set một phần của phương pháp có thể nâng cao sự kiện thông báo như INotifyPropertyChanged.PropertyChanged mà các đối tượng khác có thể lắng nghe và cập nhật các giá trị hiển thị. Đây là một phần quan trọng của ràng buộc dữ liệu nâng cao.

Tóm lại, bộ nhớ dữ liệu "Chuẩn" mới có các tiện ích nâng cao, sau đó chỉ lưu trữ dữ liệu trong các thành viên của lớp. Bằng cách tránh các thuộc tính thông thường, bạn có thể thực hiện tất cả các chức năng, nhưng vì việc triển khai có thể khác với từng người, đây là tiêu chuẩn giúp mọi người xác định/truy cập/xác thực/thông báo lưu trữ dữ liệu trong một biểu mẫu duy nhất được gọi là "Thuộc tính"

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