2009-06-03 17 views
5
Class c = new Class({ Prop = "Initial" }); 

Tôi có lớp ở trên. Làm thế nào bạn sẽ tạo ra một phương pháp để sửa đổi nó?Bạn có muốn trả lại đối tượng đã sửa đổi hay không?

public Class ModifyIt(Class c) 
{ 
    c.Prop = "changed"; 
    return c; 
} 

hoặc

public void ModifyIt(Class c) 
{ 
    c.Prop = "changed"; 
} 

Sau đó gọi là như thế này ...

Class c = ModifyIt(c); 
Console.WriteLine(c.Prop); 
// changed 

hay này

ModifyIt(c) 
Console.WriteLine(c.Prop); 
// changed 

Whats sở thích của bạn?

+0

Tại sao bạn chuyển 'Lớp x' làm tham số cho ModifyIt()? Phương pháp của bạn không chỉ lấy trường hợp Lớp là 'cái này'? Với mã bạn có tất cả các câu trả lời khác liên quan đến chuỗi sẽ không hoạt động thực sự. Đối với tôi câu hỏi sẽ là nếu lớp của bạn có nhiều hơn một loại giá trị, trong trường hợp đó bạn không nên sửa đổi các trường hợp của bạn, mà là trả lại một trường hợp mới với kết quả của hoạt động. – van

Trả lời

2

Điều thú vị khi thực hiện nó theo cách đầu tiên, trong đó bạn thực sự trả lại mục sau khi thay đổi nó, là nó cho phép chuỗi phương pháp. Có nghĩa là bạn có thể làm một cái gì đó như thế này:

c.ModifyIt("hello").MessWithIt("World").ReallyScrewWithIt("!!!"); 

Nếu nó có ý nghĩa với lớp học cụ thể của bạn, nơi bạn có thể thấy trước nhu cầu chaining, sau đó trả lại ví dụ. Nếu không, sau đó bạn chỉ có thể làm cho nó void. Một ví dụ điển hình của việc này là lớp StringBuilder cho phép bạn làm điều gì đó như:

myStringBuilder.Replace("!", "?").Append("Something").Remove(4,3); 
+0

"Điều thú vị khi thực hiện nó theo cách thứ hai [...] là nó cho phép chuỗi phương pháp". Tôi nghĩ bạn có nghĩa là cách đầu tiên. Xin lỗi vì nhận xét, chưa thể chỉnh sửa. – PatrikAkerstrand

+0

Rất tiếc, chỉ cần chỉnh sửa bài đăng của tôi, cảm ơn! – BFree

6

Cá nhân, tôi thích command-query separation - ví dụ, phương pháp trở về một kết quả không nên mutators, và ngược lại. Tôi hiểu các đối số cho đám đông return this, tức là, sự dễ dàng của "chain" gọi:

foo.ChangeThis(23).ChangeThat(45).AndAlso(67); 

nhưng nó chắc chắn không phải là quá xấu mã những trường hợp như

var x=foo; 
x.ChangeThis(23); x.ChangeThat(45); x.AndAlso(67); 

Trong khi đó, những ưu điểm của " tách truy vấn lệnh "(trong phần lớn các trường hợp, mặc dù phải thừa nhận không phải 100% trong số đó), như được thảo luận tại URL wikipeida đó, chịu đựng ...

3

Lựa chọn trả về một thể hiện của đối tượng hoặc không phụ thuộc về tình hình.

Một trường hợp phổ biến đối với sự trở lại đối tượng bằng phương pháp này được nhìn thấy trong các builder pattern, chẳng hạn như lớp StringBuilder:

new StringBuilder("Hello").Append(" ").Append("World!").ToString(); 

Nhưng nói chung, nếu như method chaining sẽ không được thực hiện, tôi sẽ chọn không trả lại bất cứ điều gì. Nếu trường hợp sử dụng phổ biến là không sử dụng đối tượng được trả về (và chỉ thả nó), điều đó dường như là một sự lãng phí.

0

Trước hết, nếu bạn chỉ thay đổi một thuộc tính, tôi sẽ không có chức năng sửa đổi riêng biệt chút nào; Tôi chỉ thay đổi trực tiếp tài sản. Với cách đó, giả sử bạn đang đưa ra một ví dụ đơn giản về một cái gì đó phức tạp hơn, với một vài thay đổi khác nhau bên trong hàm sửa đổi.

Tôi muốn sử dụng đối tượng trả về đối tượng 'Lớp'. Nó cho phép bạn kết nối nhiều cuộc gọi với nhau. Một lần nữa, tôi giả sử đây là một ví dụ đơn giản của một hệ thống thực sự phức tạp hơn; giả sử thay vào đó bạn có MakeModification(), MakeAnotherModification() và MakeAThirdModification().Nếu bạn trả lại đối tượng 'Class', bạn có thể lấy tính tinh vi cú pháp sau:

Class c = new Class(); 
c.MakeModification().MakeAnotherModification().MakeAThirdModification(); 
0

Thực ra tôi thích phong cách thứ hai là phương pháp này là một mutator, do đó, một giá trị mới có thể sẽ không được trả lại, thay vì giá trị thực tế dự kiến ​​sẽ được sửa đổi. Tuy nhiên bạn có thể cần phải chỉ ra rằng ModifyIt chấp nhận một biến ref chỉ để chỉ ra rằng c thực tế sẽ được sửa đổi. c ở đây được chuyển bởi giá trị, mặc dù đó là một kiểu tham chiếu, vẫn có sự khác biệt giữa việc chuyển các kiểu tham chiếu theo giá trị và chuyển kiểu tham chiếu theo ref. Thấy như sau:

public void ModifyIt(Myclass c) { c = new MyClass(); } 

trong trường hợp trên biến c sẽ được truyền theo giá trị (tức là một bản sao từ tài liệu tham khảo sẽ được thông qua và sửa đổi để trỏ đến một đối tượng mới instanitiated, do đó có nghĩa là bạn sẽ có hai đối tượng của kiểu MyClass trong trường hợp này Dưới đây là một ví dụ để minh họa:.

Myclass s = new MyClass() { prop = "value" }; ModifyIt(s); Console.WriteLine(s.prob); // this will print "value" 

dù MOdifyIT instanitaited các referenct đến một đối tượng mới mà nên có nghĩa prob sẽ được khởi tạo null, nó thực sự didn' t instantiate s, nó khởi tạo một bản sao của s. không giống như ca se nếu s được thông qua bởi ref.
Hy vọng điều này sẽ hữu ích!

1

Cá nhân tôi thích xây dựng một chức năng như ModifyIt và đặt nó vào lớp tôi đang tạo nếu có thể. Lý do tôi nói đó là trong cả hai phương pháp tôi đang sửa đổi các biến gọi là nguyên nhân tôi vượt qua nó bằng cách tham khảo. Đương nhiên, tôi không thể làm điều đó cho tất cả các chức năng, nhưng việc đặt ref trong lời gọi hàm giúp làm rõ rằng tôi đang chuyển một biến theo tham chiếu, chứ không phải truyền một biến theo giá trị. Ví dụ:

public Class ModifyIt(ref Class c) 

Tại sao? Vì tôi phải quên đi khi tôi quay lại và đọc mã mà tôi đã chuyển giá trị bằng cách tham khảo và sau đó nhiều khả năng sẽ làm điều gì đó "xấu" với mã.

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