Get set trong c# là gì

Nếu bạn học qua OOP bạn sẽ học tới phần đóng gói, che dấu dữ liệu phía sau, không cho truy cập trực tiếp mà phải thông qua một thằng cò trung gian.

Ví dụ bạn muốn lấy tiền, bạn không thể mở tủ tiền ra lấy trực tiếp được, mà phải thông qua bố hoặc mẹ bạn. Khi đó Getter nói chung làm nhiệm vụ như mẹ bạn có quyền xử lý số tiền đó trước khi đưa cho bạn. Setter tương tự.

Phía trên Setter hay Getter mới chỉ là định nghĩa. Khi ta thực hiện nó sẽ trông như sau.

Với Java bạn thường thông qua một method get...[] hay set...[] mà bên trong xử lý sao đó mà get trả về kiểu của data cần lấy ra, còn set thường sẽ trả về void.

public Money getMoney[] { // Đặt xử lý của bạn chỗ này return this._money; } public void setMoney[Money value] { // Đặt xử lý của bạn chỗ này this._money = value; }

Với C# thì nó rút gọn lại thành mấy cái keyword get set cho nó tiện hơn thôi. Còn lại bản chất nó như một method.

Chào anh chị ạ,

Em đang học C# trên website và học đến phần C# OOP. Bản thân em tự dưng có một thắc mắc khi em học đến Class. Em giả sử em có một đoạn code sau ạ:

class SinhVien { private double diemTB; public double DiemTB { get { return double; } set { diemTB = value; } } }

Em để ý ở trường học của em cũng sử dụng tương tự HowKTeam, nhưng em không hiểu tại sao phải dùng private chi cho mắc công, tốn sức rồi lại sử dụng thêm get, set, trong khi đó mình có thể dùng trực tiếp public để truy cập cho dễ cũng được mà.

class SinhVien { public double diemTB; }

Em có hỏi thì một số bạn cũng có trả lời em là do bảo mật không cho truy cập gì ấy nhưng em vẫn chưa hình dung được.

Rất mong anh chị giải đáp, em xin cảm ơn ạ.

Ngày làm việc của mình thường bắt đầu bằng việc mở một project nào đó, ngắm nghía và review chúng. Hôm nay chợt mình nhìn thấy đoạn code get set này làm mình nhớ tới câu chuyện ngày trước:

private int Month= 1;

public int Month

{

get {return _Month}

set

{

if [value>=1 && value bar = bar; return *this; }

Điều này cho phép gọi nhiều bộ cài đặt như vậy:

Foo foo; foo.SetBar["Hello"].SetBaz["world!"];

Tuy nhiên, nó không được chấp nhận rộng rãi như một điều tốt.

__declspec [thuộc tính] : Visual C ++ cung cấp phần mở rộng không chuẩn này để người gọi có thể sử dụng lại cú pháp thuộc tính. Điều này làm tăng tính hợp pháp trong lớp một chút, nhưng làm cho mã người gọi trông thân thiện hơn nhiều.

Vì vậy, kết luận, có một chút công việc khó khăn hơn, nhưng một số ít các quyết định cần thực hiện trong C ++. Điển hình ;]

6 hữu ích 4 bình luận chia sẻ

answer

4

Tôi hầu như không bao giờ sử dụng getters và setters trong mã của riêng tôi. Câu trả lời của Veefu có vẻ tốt với tôi.

Nếu bạn khăng khăng muốn có getters và / hoặc setters, bạn có thể sử dụng macro để cắt bớt tấm nồi hơi.

#define GETTER[T,member] const T& Get##member[] const { return member; } #define SETTER[T,member] void Set##member[const T & value] { member = value; } class Foo { public: GETTER[std::string, bar] SETTER[std::string, bar] private: std::string bar; }

4 hữu ích 0 bình luận chia sẻ

answer

3

Lấy và thiết lập các thành viên dữ liệu qua các thành viên dữ liệu: Xấu .
Lấy và thiết lập các yếu tố của phần trừu tượng: Tốt .

3 hữu ích 0 bình luận chia sẻ

answer

3

Các lập luận chống lại Get / Set về mặt thiết kế API trong ví dụ ngân hàng được đưa ra. Không để lộ các trường hoặc thuộc tính nếu chúng cho phép người dùng vi phạm các quy tắc kinh doanh của bạn.

Tuy nhiên, khi bạn đã quyết định rằng bạn cần một trường hoặc thuộc tính, hãy luôn sử dụng thuộc tính.

Các thuộc tính tự động trong c # rất dễ sử dụng và có nhiều trường hợp [liên kết dữ liệu, tuần tự hóa, v.v.] không hoạt động với các trường, nhưng yêu cầu thuộc tính.

3 hữu ích 0 bình luận chia sẻ

answer

1

Nếu bạn đang phát triển các thành phần COM thì có, nó rất phổ biến.

1 hữu ích 0 bình luận chia sẻ

answer

1

lấy và thiết lập là một nỗi đau gây ra cho mọi người nếu bạn phải sử dụng chúng trong bất kỳ ngôn ngữ nào.

Eiffel làm tốt hơn rất nhiều ở chỗ tất cả những gì khác biệt là lượng thông tin bạn phải cung cấp để có câu trả lời - một hàm có 0 parms giống như việc truy cập vào một biến thành viên và bạn có thể thay đổi tùy ý giữa chúng.

Khi bạn kiểm soát cả hai mặt của một giao diện, định nghĩa của giao diện dường như không phải là một vấn đề lớn như vậy. Tuy nhiên, khi bạn muốn thay đổi chi tiết triển khai và nó dẫn đến việc biên dịch lại mã máy khách như trường hợp phổ biến trong C ++, bạn muốn có thể giảm thiểu điều này càng nhiều càng tốt. Vì pImpl và get / set như vậy sẽ được sử dụng nhiều hơn trong các API công khai để tránh những thiệt hại như vậy.

1 hữu ích 0 bình luận chia sẻ

answer

1

Phương thức Get và Set rất hữu ích nếu bạn có các ràng buộc trong một giá trị biến. Ví dụ, trong nhiều mô hình toán học, có một ràng buộc để giữ một biến float nhất định trong phạm vi [0,1]. Trong trường hợp này, Nhận và Đặt [Đặt đặc biệt] có thể đóng một vai trò tốt:

class Foo{ public: float bar[] const { return _bar; } void bar[const float& new_bar] { _bar = [[new_bar = 0]]?new_bar:_bar; } // Keeps inside [0,1] private: float _bar; // must be in range [0,1] };

Ngoài ra, một số thuộc tính phải được tính toán lại trước khi đọc. Trong những trường hợp đó, có thể mất rất nhiều thời gian tính toán không cần thiết để tính toán lại từng lớp biểu bì. Vì vậy, một cách để tối ưu hóa nó là chỉ tính toán lại khi đọc thay thế. Để làm như vậy, hãy nạp chồng phương thức Get để cập nhật biến trước khi đọc nó.

Ngược lại, nếu không cần xác thực giá trị đầu vào hoặc cập nhật giá trị đầu ra, thì việc đặt thuộc tính công khai không phải là tội và bạn có thể thực hiện nó.

1 hữu ích 0 bình luận chia sẻ

answer

0

Vâng, get và set rất phổ biến trong thế giới c ++.

0 hữu ích 5 bình luận chia sẻ

answer

0

Nếu bạn sử dụng C ++ / CLI làm biến thể của C ++, thì nó có hỗ trợ thuộc tính bản địa trong ngôn ngữ, vì vậy bạn có thể sử dụng

property String^ Name;

Điều này cũng giống như

String Name{get;set;}

trong C #. Nếu bạn cần kiểm soát chính xác hơn các phương thức get / set thì bạn có thể sử dụng

property String^ Name { String^ get[]; void set[String^ newName]; }

trong tiêu đề và

String^ ClassName::Name::get[] { return m_name; } void ClassName::Name::set[String^ newName] { m_name = newName; }

trong tệp .cpp. Tôi không thể nhớ rõ, nhưng tôi nghĩ bạn có thể có các quyền truy cập khác nhau cho các phương thức get và set [công khai / riêng tư, v.v.].

Colin

0 hữu ích 0 bình luận chia sẻ

answer

-3

Trình biên dịch sẽ phát ra set_ và get_ nếu bạn xác định một thuộc tính, vì vậy nó thực sự chỉ cần lưu một số thao tác nhập.

Đây là một cuộc thảo luận thú vị. Đây là một cái gì đó từ cuốn sách yêu thích của tôi "CLR qua C #".

Đây là những gì tôi đã trích dẫn.

Cá nhân tôi không thích các thuộc tính và tôi ước rằng chúng không được hỗ trợ trong Microsoftm.NET Framework và các ngôn ngữ lập trình của nó. Lý do là vì các thuộc tính trông giống như các trường nhưng chúng là các phương thức. Điều này đã được biết đến là nguyên nhân gây ra hiện tượng hỗn tạp. Khi một lập trình viên thấy mã có vẻ như đang truy cập vào một trường, có nhiều giả định mà lập trình viên đưa ra có thể không đúng với một thuộc tính. Ví dụ,

  • Thuộc tính có thể chỉ đọc hoặc chỉ ghi; truy cập trường luôn
    có thể đọc và ghi được. Nếu bạn xác định
    một thuộc tính, tốt nhất là cung cấp cả hai
    phương thức truy cập get và set.
  • Một phương thức thuộc tính có thể ném ra một ngoại lệ; truy cập trường không bao giờ ném
    một ngoại lệ.

  • Một thuộc tính không thể được truyền dưới dạng tham số out hoặc ref cho một phương thức; một lĩnh vực có thể.

  • Một phương thức thuộc tính có thể mất nhiều thời gian để thực thi; truy cập trường luôn
    hoàn thành ngay lập tức. Một
    lý do phổ biến để sử dụng thuộc tính là
    thực hiện đồng bộ hóa luồng, điều này có thể dừng luồng mãi mãi, và
    do đó, không nên
    sử dụng thuộc tính nếu
    yêu cầu đồng bộ hóa luồng . Trong tình huống đó, một phương pháp được ưu tiên hơn. Ngoài ra, nếu lớp của bạn có thể được truy cập từ xa [ví dụ:
    lớp của bạn có nguồn gốc từ
    System.MashalByRefObject], việc gọi
    phương thức thuộc tính sẽ rất
    chậm và do đó, một phương thức được
    ưu tiên hơn một thuộc tính. Theo
    ý kiến của tôi , các lớp bắt nguồn từ
    MarshalByRefObject không bao giờ nên sử dụng
    tính chất.

  • Nếu được gọi nhiều lần liên tiếp, một phương thức thuộc tính có thể trả về
    một giá trị khác nhau mỗi lần; một
    trường trả về cùng một giá trị mỗi
    lần. Lớp System.DateTime có thuộc tính Now chỉ đọc trả về
    ngày và giờ hiện tại. Mỗi lần bạn truy vấn thuộc tính này, nó sẽ
    trả về một giá trị khác. Đây là một
    sai lầm và Microsoft mong muốn rằng
    họ có thể sửa lớp này bằng cách biến
    Now thành một phương thức thay vì một thuộc tính.

  • Một phương pháp thuộc tính có thể gây ra các phản ứng phụ có thể quan sát được; truy cập trường không bao giờ làm. Nói cách khác, người dùng của một loại sẽ có thể đặt các
    thuộc tính khác nhau được xác định bởi một loại theo bất kỳ
    thứ tự nào mà họ chọn mà không
    nhận thấy bất kỳ hành vi khác nhau nào trong
    loại.

  • Một phương thức thuộc tính có thể yêu cầu thêm bộ nhớ hoặc trả về một
    tham chiếu đến một cái gì đó không
    thực sự là một phần của trạng thái của đối tượng, vì vậy việc sửa đổi đối tượng được trả về
    không có ảnh hưởng gì đến đối tượng ban đầu;
    truy vấn một trường luôn trả về một
    tham chiếu đến một đối tượng được
    đảm bảo là một phần của trạng thái của đối tượng ban đầu. Làm việc với một thuộc
    tính trả về một bản sao có thể
    rất khó hiểu đối với các nhà phát triển và
    đặc điểm này thường không được ghi lại.

-3 hữu ích 1 bình luận chia sẻ

Chủ Đề