2009-04-14 31 views
8

Chúng ta hãy nói một chút rằng C# cho phép nhiều giá trị lợi nhuận theo nghĩa tinh khiết nhất, nơi mà chúng tôi mong chờ để xem cái gì đó như:C# - Đường cú pháp cho các tham số ngoài?

string sender = message.GetSender(); 
string receiver = message.GetReceiver(); 

đầm để:

string sender, receiver = message.GetParticipants(); 

Trong trường hợp đó, Tôi không phải hiểu các giá trị trả về của phương thức cho đến khi tôi thực sự thực hiện cuộc gọi phương thức. Có lẽ tôi dựa vào Intellisense để cho tôi biết giá trị trả lại (s) tôi đang xử lý, hoặc có lẽ tôi đang tìm kiếm một phương thức trả về những gì tôi muốn từ một lớp tôi không quen thuộc.

Tương tự như vậy, chúng tôi có một cái gì đó như thế này, hiện nay, trong C#:

string receiver; 
string sender = message.GetParticipants(out receiver); 

nơi lập luận để GetParticipants là một tham số ra chuỗi. Tuy nhiên, đây là một chút khác biệt so với ở trên bởi vì nó có nghĩa là tôi phải preempt với, hoặc ít nhất là quay trở lại và viết, mã mà tạo ra một biến để giữ kết quả của tham số out. Đây là một chút phản trực giác.

Câu hỏi của tôi là, có bất kỳ đường cú pháp nào trong C# hiện tại, cho phép nhà phát triển đưa ra tuyên bố này trong cùng một đường với lời gọi phương thức không? Tôi nghĩ rằng nó sẽ làm cho phát triển một (nhỏ) chút chất lỏng hơn, và cũng làm cho mã dễ đọc hơn nếu tôi đã làm một cái gì đó như:

để cho thấy rằng người nhận đã được khai báo và giao ngay tại chỗ.

+0

Ví dụ C# hiện tại của bạn cũng nên thêm công cụ sửa đổi "ra" vào đối số *: string sender = message.GetParticipants (out receiver); –

+0

chỉnh sửa GetParicipants, tôi không có quyền làm điều đó –

+0

Điều này đã được [đề xuất như một tính năng có thể cho C# 6.0] (http://damieng.com/blog/2013/12/09/probable-c-6- 0 tính năng minh họa). –

Trả lời

9

Không, hiện tại không có bất kỳ đường cú pháp nào. Tôi đã không nghe nói về bất kỳ ý định để giới thiệu bất kỳ một trong hai.

Tôi không thể nói rằng tôi sử dụng thông số out thường đủ để thực sự là một mối quan tâm đáng kể đối với tôi (có các tính năng khác mà tôi muốn nhóm C# dành cho họ) nhưng tôi đồng ý rằng nó hơi khó chịu.

+0

Làm thế nào là việc thực hiện hiện tại một tiêu chuẩn kép ...? –

+0

Vì chúng không trả về giá trị, chúng là các tham số. Không có "tiêu chuẩn kép" - chúng là những thứ khác nhau, được đối xử khác nhau. Nó không giống như bạn đại diện cho giá trị trả về như là một tham số khởi đầu hoặc bất cứ điều gì như thế - tại * rằng * điểm nó sẽ là công bằng để gọi nó là một tiêu chuẩn kép. –

+0

Lưu ý rằng các tham số * không * giống như giá trị trả lại. Bạn có thể gán giá trị của tham số ngoài trong phương thức và thay đổi đó xảy ra ngay lập tức. Bạn có thể thấy điều này nếu bạn gọi một phương thức và sử dụng một biến cá thể cho đối số ngoài. –

0

Tốt nhất bạn sẽ phải sử dụng var thay vì loại rõ ràng, trừ khi bạn muốn hạn chế tất cả các giá trị trả lại nhiều cùng loại (không có khả năng thực tế). Bạn cũng sẽ giới hạn phạm vi của biến; hiện tại bạn có thể khai báo một biến ở một phạm vi cao hơn và khởi tạo nó trong một tham số ngoài. Với cách tiếp cận này, biến sẽ nằm ngoài phạm vi trong cùng một khối với nhiệm vụ của nó. Rõ ràng điều này là có thể sử dụng trong một số trường hợp, nhưng tôi sẽ không muốn thực thi điều này như là quy tắc chung. Rõ ràng bạn có thể để tùy chọn 'out' tại chỗ, nhưng rất có thể là mọi người sẽ viết mã cho một cách tiếp cận này hay cách khác.

+0

Việc sử dụng var không đúng, đường cú pháp, nếu nó tồn tại, chỉ cần khai báo một biến mới trong cùng phạm vi như bạn đã đề cập, và chuyển nó vào phương thức gán. Do đó, mỗi thông số sẽ được nhập tự nhiên. – JoshJordan

+0

chuỗi param1, int param2 = FuncCall (param3)? –

+0

Bài đăng đã hỏi về đường cú pháp của biểu mẫu: chuỗi được trả về = FuncCall (trong tham số int2, ra chuỗi param3). Tuy nhiên, những gì bạn đã đăng sẽ là một hình thức khả thi, vâng. – JoshJordan

-1

Hãy thử đoạn mã sau

Participants p = message.GetParticipants(); 
log(p.sender,p.receiver); 
-1

Tôi nghĩ rằng đây không phải là những gì bạn muốn. Bạn có thể đã gặp phải một đoạn mã nơi bạn sẽ có thích điều đó. Nhưng biến popping ra khỏi hư không vì họ đã được giới thiệu trong danh sách tham số sẽ là một cơn ác mộng cá nhân (đối với tôi :))

Nhiều giá trị trả lại có nhược điểm nghiêm trọng từ quan điểm của tính di động/bảo trì. Nếu bạn thực hiện một hàm trả về hai chuỗi và bây giờ bạn muốn nó trả lại ba, bạn sẽ phải thay đổi tất cả mã sử dụng hàm này. Một loại bản ghi trả lại tuy nhiên thường chơi tốt trong các tình huống phổ biến như vậy.

bạn có thể mở hộp Pandora ;-)

Đối với dòng nén chặt:

string s1, s2; s1 = foo.bar(s2); 

dòng có thể bất kỳ chiều dài, vì vậy bạn có thể đóng gói một số công cụ phổ biến thành một. Chỉ cố gắng sống với dấu chấm phẩy.

+1

Xin vui lòng không nhỏ gọn nó ... – Jabe

+0

Vâng, có rất nhiều, nhiều cấu trúc có hàm ý khắc nghiệt cho khả năng bảo trì đã có, và các nhà phát triển cần phải học cách làm việc với họ. Trong trường hợp này, nó sẽ có nhiều khả năng không thích hợp để giới thiệu một phương thức khác có cùng tên nhưng với chữ ký trả về khác. – JoshJordan

+0

Vấn đề là các biến "sắp ra khỏi hư không" là những gì chúng ta có cho một giá trị trả về duy nhất, nếu chúng ta chọn khai báo và gán. Việc thiếu một cơ sở để làm điều này cho nhiều giá trị trả về (hoặc các tham số ngoài) cho chúng ta một tiêu chuẩn kép. – JoshJordan

5

.NET 4 sẽ thêm khái niệm Tuple, đề cập đến vấn đề này. Thật không may, ngôn ngữ C# sẽ không cung cấp bất kỳ hỗ trợ ngôn ngữ nào cho "binducturing bind".

+2

Nó được gọi là "ràng buộc phá hoại". –

2

Bạn cũng có thể trả lại số Tuple<T,U> hoặc nội dung tương tự. Tuy nhiên, vì bạn muốn trả về hai chuỗi, nó có thể gây nhầm lẫn.

Tôi sử dụng cấu trúc Tuples của BclExtras library rất tiện dụng (tìm thấy nó trên SO, cảm ơn bạn JaredPar!).

4

Cá nhân, tôi thích sự bất tiện được giới thiệu khi sử dụng các tham số. Nó giúp tôi suy nghĩ về việc liệu phương pháp của tôi có thực sự làm những gì nó nên hay không, hoặc nếu tôi nhồi nhét quá nhiều chức năng vào nó. Điều đó nói rằng, có lẽ gõ động trong C# 4.0/.Net 4 sẽ giải quyết một số mối quan tâm của bạn.

dynamic participant = message.GetParticipants(); 

var sender = participant.Sender; 
var recipient = participant.Recipient; 

nơi

public object GetParticipants() 
{ 
    return new { Sender = ..., Recipient = ... }; 
} 
+0

Yuck, điều này có vẻ sooo xấu xí! –

2

Tôi không nghĩ rằng chức năng như vậy tồn tại, nhưng nếu nó được thực hiện trong một cách tương tự như mảng trong perl mà có thể có ích thực sự.

Trong perl Bạn có thể gán một mảng vào danh sách các biến trong dấu ngoặc đơn. Vì vậy, bạn có thể ví dụ như làm điều này

 
($user, $password) = split(/:/,$data); 
2

đâu này làm tôi phát cáu nhất: vì không có tình trạng quá tải của (nói) DateTime.TryParse mà không mất một tham số out, bạn không thể viết

if (DateTime.TryParse(s, out d)) 
{ 
    return new ValidationError("{0} isn't a valid date", s); 
} 

mà không khai báo d. Tôi không biết nếu đây là một vấn đề với các thông số out hoặc chỉ với phương pháp TryParse được thực hiện, nhưng nó gây phiền nhiễu.

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