30/09/2018, 20:19
Cho mình hỏi về get set trong c#
Chào mọi người. Cho em xin hỏi về sự khác nhau giữa 2 cách khai báo như nhau trong c#:
public class myClass
{
//cái này
public int myInt;
//với cái này
public int myInt1 {get; set;}
}
Em thấy cả 2 rất giống nhau đều có thể lấy hoặc gán dữ liệu vào biến. Vậy cho em hỏi là nó thực sự khác nhau chỗ nào ạ.
Bài liên quan
Nó là bao đóng. Tương tự getter và setter của java.
Anh có thể nói rõ hơn được không?
Bao đóng là gì?
Khai báo như thế nào là tốt nhất?
Vậy khai báo như vậy nó có thực sự khác biệt gì không a?
(em newbie mong anh có thể chỉ thêm)
Vậy thì bạn nên đọc lại lý thuyết lập trình hướng đối tượng nhé. Giải thích rất dài dòng và trong 1 vài comment ko thể trả lời hết được
Vậy thì cho e hỏi là khai báo vậy nó khác nhau chỗ nào ạ:
Không khác nhau gì cả.
Chỉ khác nhau trong 1 số trường hợp cụ thể, ví dụ khi ở trong hàm set, bạn muốn kiểm tra giá trị được set rồi mới gán giá trị.
set { if(value >0 ) myint2 = value; }
Vâng. Em cám ơn nhé
Là cách viết ngắn gọn của :
public int myInt1 {get; set;}
thìmyInt1
gọi là property. PropertymyInt1
có thể xem là 2 hàm: getter và setter. Compiler sẽ tự động tạo:private int _myInt1
int get_myInt1() { return _myInt1; }
int set_myInt1(int value) { _myInt1 = value; return _myInt1; }
thay vì lấy giá trị của
_myInt1
bằng cách viếtobj.get_myInt1()
thì với property có thể viết ngắn gọn làobj.myInt1
.thay vì gán giá trị cho
_myInt1
bằng cách viếtobj.set_myInt1(10)
thì với property có thể viết ngắn gọn làobj.myInt1 = 10
.nếu chỉ viết
{get; set;}
ko thì chả khác gì khai báopublic int myInt1;
cả. Công dụng của property được áp dụng ở chỗ khác. Ví dụ 1 class Character có private int hp. Thay vì phải viết hàmvoid addHealth(int amount)
thì có thể viết 1 property setter cho hp:như vậy có thể viết
character.HP = character.HP + 20; //tăng 20 máu
mà vẫn bảo đảm logic là hp của nhân vật ko vượt quá max hp ví dụ là 100. Đơn giản hơn là gọicharacter.addHealth(20);
vì phải nhớ phương thứcaddHealth
Mặc dùHP
ko phải là 1 thuộc tính (attribute) của classCharacter
nhưng ở đây ta có thể xem nó y như là thuộc tínhhp
vậy. Ngoài ra gọicharacter.HP
gọn gàng hơn gọicharacter.getHp()
nhiều.chuẩn rồi.hehe.c# dùng property để đóng gói với tự nhiên hơn
Mình ko thực sự hiểu cách viết
public int myInt1{get;set;}
Nó có ý nghĩa gì trong vấn đề đóng gói
Nếu chỉ viết {get;set;} như thế tại sao ta ko viết
public int myInt1;
public int myInt1{get;set;}
Cách viết này được gọi là auto-properties (tự động tạo thuộc tính),
nó tương đương với
Còn tại sao ta không dùng
public int myInt1;
mặc dù nó tương đương?
Nó liên quan tới khái niệm Encapsulation (đóng gói trong OOP)
Với cách1: tuy bạn gọi obj.myInt1=2, nhưng thực ra nó sẽ gọi obj.setMyInt1(2)
Với cách 2: bạn gọi obj.myInt1=2 là set trực tiếp giá trị myInt1 thành 2.
Vậy đóng gói có tác dụng gì?
đọc lại OOP về Encapsulation là hiểu thôi mà (capsule là con nhộng, viên thuốc ý: bạn có nhìn thấy thành phần gì bên trong không? Đóng gói tức là bạn chỉ biết phía bên ngoài vậy thôi, đọc hướng dẫn sử dụng mà dùng (API) chứ không ai chọc nó ra xem thành phần thuốc rồi dùng cả ^^)
Cũng có khá nhiều tranh luận có nên đóng gói hay không đóng gói. Rõ ràng với code không đóng gói, sẽ nhanh hơn, dễ hiểu hơn, trong sáng hơn, nhất là debug thì public nó show hàng lồ lộ ra, thích hơn hẳn ^^, rồi serialize/deserialize nữa, dễ hơn rất nhiều.
Một số trường hợp cần đóng gói như:
mình inject chứ không khai báo
Injection giúp trong việc làm TDD, vì mình hoàn toàn có thể cho một conn mock (là một conn luôn đúng), chứ nếu cho conn thật, nhỡ nó fail thì cả cái class của mình fail hết à.
Khi design chỉ cần nhớ nguyên tắc KISS keep it simple and small, là được. Nếu chỉ có bạn dùng class đó, dùng public cũng không sao cả, vừa nhanh, vừa đỡ tốn bộ nhớ.
JavaWorld
Why getter and setter methods are evil
The getter/setter idiom is a commonplace feature in many Java programs. Most of these accessor methods, however, are unnecessary and can severely impact your systems' maintainability. Using accessors violates the basic object-oriented (OO) principle...
Ngay cả việc viết auto-property cũng giúp việc đóng gói KISS đó (viết có một dòng, thay vì bao nhiêu dòng lê ta thê).
Mình có câu hỏi, vậy public int myInt1{get,set} là property hay method? ^^
hình như KISS là “keep it simple, stupid” mà
Ừ, chuẩn là stupid, nhưng dùng stupid trong lập trình nghe hơi … dummy quá. Dùng biến thể của nó cho hợp lý hơn ^^
rõ ràng là auto property get set vi phạm quy tắt đóng gói. Nếu chỉ viết
{get; set;}
“về cách sử dụng” thì chả khác gì khai báo biến public cả, nên hạn chế hoặc ko viết như vậy. Nên viết thêm kiểm tra điều kiện cho getter setter nữa.http://blog.codinghorror.com/properties-vs-public-variables/
chắc là boss này trả lời đầy đủ vấn đề property
Nếu chỉ có get, set thì về ý nghĩa sử dụng đa phần không khác gì biến public. Nhưng đó là cách viết của 1 property hết sức đơn sơ và bình thường và thực tế thì nó sẽ không chỉ có get, set. Khi đó bạn mới thấy khác biệt với biến public.
Ví dụ 3 cách thế này bạn sẽ thấy nó khác, bạn thử sử dụng xem nó khác thế nào.
3 cách dùng bên dưới thì rõ ràng là có sự khác biệt. Nhưng nếu chỉ {get;set;} mình thấy không có ý nghĩa gì cả (tất nhiên về bản chất 1 cái là biến, 1 cái là property). Ko biết mình có hiểu sai không nhưng như thế giống như người code đang dùng cửa kính cho nhà tắm vậy, vẫn là đóng cửa nhưng mà
Nhưng mà không sờ được
Dù gì thì vẫn hơn là không có kính
Cám ơn a @Phan_Hoang nhé. Cứ thắc mắc từ bữa giờ. Bây giờ thì e đã hiểu rồi