2010-09-17 61 views
5

hiện tại tôi đang nghĩ về việc đóng gói dữ liệu trong C# và tôi hơi bối rối một chút. Những năm trước đây, khi tôi bắt đầu học lập trình với C++, giáo sư của tôi nói với tôi: - "Tạo một lớp và giấu nó các thành viên dữ liệu, vì vậy nó không thể được thao tác trực tiếp từ bên ngoài"Đóng gói dữ liệu trong C# bằng cách sử dụng các thuộc tính

Ví dụ: Bạn đang phân tích cú pháp một tệp XML và lưu trữ dữ liệu được phân tích cú pháp vào một số thành viên dữ liệu bên trong lớp trình phân tích cú pháp.

Bây giờ, khi tôi đang xem C#. Bạn có tài sản. Tính năng này làm cho trạng thái nội bộ/dữ liệu nội bộ của một lớp hiển thị bên ngoài. Không còn gói gọn nữa. Đúng?

private string _mystring; 
public string MyString 
{ 
    get {return _mystring;} 
    set {_mystring = value;} 
} 

Từ quan điểm của tôi không có sự khác biệt giữa các thành viên làm dữ liệu công cộng hoặc có đặc tính công cộng, trong đó có getter và setter, nơi bạn vượt qua các thành viên dữ liệu cá nhân thông qua.

Ai đó có thể giải thích cho tôi không?

Cảm ơn

Trả lời

13

Dữ liệu cá nhân được đóng gói bởi chính thuộc tính. Cách duy nhất để truy cập dữ liệu là thông qua tài sản.

Trong trường hợp của bạn ở trên, có rất ít lý do để sử dụng thuộc tính. Tuy nhiên, nếu sau này bạn cần phải thêm một số xác thực, bạn có thể, mà không vi phạm API, nghĩa là:

private string _mystring; 
public string MyString 
{ 
    get {return _mystring;} 
    set 
    { 
     if (IsAcceptableInput(value)) 
     _mystring = value; 
    } 
} 

Hãy nhớ rằng một thuộc tính, trong .NET thực sự là một cú pháp rõ ràng hơn cho 2 phương pháp - một phương pháp cho phần nhận tài sản và một phần cho phần thuộc tính. Nó cung cấp tất cả các gói giống như một cặp các phương thức trong C++, nhưng một cú pháp đẹp hơn (cho là) ​​để sử dụng.

+0

Thanks a lot. Điều này đã làm rõ một vài điều. – Ferhat

0

Lợi ích của thuộc tính là sau này, bạn có thể quyết định bổ sung xác nhận vv với phương pháp setter, hoặc thực hiện các phương thức getter sao một số tính hoặc bộ nhớ đệm, và không ai trong số các mã mà đã kêu gọi của bạn tài sản sẽ cần thay đổi - vì giao diện của lớp vẫn ổn định

1

Vẫn có gói dữ liệu, nếu bạn cần. Việc đóng gói dữ liệu không phải là ẩn nó khỏi máy khách của lớp hoặc làm cho nó không thể truy cập được, đó là về việc đảm bảo một giao diện nhất quán và trạng thái đối tượng bên trong.

Giả sử bạn có một đối tượng đại diện cho một chiếc xe thay đổi thanh và thuộc tính để đặt tốc độ. Bạn có thể biết rằng bạn nên thay đổi các bánh răng ở giữa các khoảng tốc độ, vì vậy đó là nơi đóng gói đi kèm.

Thay vì chỉ đơn giản là công khai tài sản, do đó cho phép truy cập công cộng mà không cần xác minh, bạn có thể sử dụng getters và setters bất động sản trong C#:

class StickShiftCar : Car 
{ 
    public int MilesPerHour 
    { 
     get {return this._milesPerHour;} 

     set 
     { 
      if (vaule < 20) 
       this._gearPosition = 1; 
      else if (value > 30) 
       this._gearPosition = 2; 
      ... 
      ... 
      this._milesPerHour = value; 
    } 
} 

Mặc dù ví dụ này không nhất thiết phải có khả năng tương thích, tôi chắc chắn bạn bắt được sự trôi dạt của mình.

2

Vì vậy, các thuộc tính không phải là miền tây hoang dã mà bạn đang dùng chúng ngay từ cái nhìn đầu tiên. Sự thật không may của OOP là rất nhiều phương pháp của bạn là getters và setters, và các thuộc tính chỉ là một cách để làm cho việc viết này trở nên dễ dàng hơn. Ngoài ra, bạn kiểm soát những gì bạn muốn tài sản để cho phép một người nào đó để làm.Bạn có thể làm cho một tài sản có thể đọc nhưng không ghi được, như vậy:

private string _mystring; 
public string MyString 
{ 
    get {return _mystring;} 
} 

Hoặc như đã đề cập bởi Reed bạn có thể có phương pháp thiết lập của bạn làm một chuyển đổi hoặc kiểm tra của bất kỳ số lượng phức tạp. Ví dụ:

private long myPrime; 
public long Prime { 
    get { return myPrime; } 
    set { 
    if (prime(value) { 
     myPrime = prime; 
    } 
    else { 
     //throw an error or do nothing 
    } 
    } 
} 

Bạn thường có tất cả giá trị bạn nhận được từ đóng gói, với một số đường cú pháp để thực hiện một số tác vụ phổ biến dễ dàng hơn. Bạn có thể làm những điều tương tự trong các ngôn ngữ khác, nó trông khác nhau.

+1

+1 Tôi vừa nhập cùng một điều :) – skajfes

0

Tìm kiếm sâu hơn một chút, tại sao giáo sư của bạn bảo bạn đóng gói? Chỉ vì nó là thiết kế hướng đối tượng thích hợp? Tại sao đó là cách thích hợp? Ngôn ngữ lập trình và mô hình chỉ là một cách để đối phó với sự phức tạp của việc xử lý một bộ xử lý để chạy mã của chúng tôi một cách dễ hiểu. Có hai độc giả mã, máy và con người. Máy sẽ tải dữ liệu một cách vui vẻ, hoặc phân nhánh đến, bất kỳ địa chỉ nào trong không gian bộ nhớ. Mặt khác, con người chúng ta thích nghĩ về "sự vật". Bộ não của chúng ta đối phó với "những thứ" có thuộc tính hoặc thực hiện hành động. Con sư tử sẽ ăn bạn, cây giáo có thể bảo vệ bạn, con sư tử là lông, ngọn giáo là nhọn. Vì vậy, chúng tôi có thể hiểu các chương trình nếu chúng được mô hình hóa là "sự vật". Các thuộc tính được cho là mô hình hóa các thuộc tính của một thứ và các phương thức được cho là mô hình hóa các hành động của mọi thứ. Trong thực tế nó có thể trở nên khá mờ nhạt và mọi thứ không thể được mô hình hóa như một hành động thế giới thực, nhưng nỗ lực để làm như vậy, khi làm tốt, có thể làm cho một chương trình dễ hiểu.

0

Bạn có thể thiếu thực tế là bạn không cần phải có thuộc tính tương ứng với tất cả các trường thành viên lớp học. Bạn có thể quyết định các thuộc tính nào sẽ thêm vào lớp của bạn và liệu chúng có thể truy cập được bên ngoài lớp hay không.

0

Nỗ lực đầu tiên sử dụng thuộc tính để đóng gói giá trị được nhận; Nhưng C# cung cấp tính năng nâng cao hơn để làm phong phú thêm các chức năng bên trong và thiết lập để làm cho thuộc tính chỉ đọc, chỉ ghi hoặc với một số điều kiện nhất định. Ví dụ, để thiết lập giá trị như

private string temp; 
public string temp 
{ 
    get 
    { 
     return temp; 
    } 
} 

sẽ tốt hơn so với sử dụng:

public readonly string Temp; 
Các vấn đề liên quan