Booleans là đối số phương thức không được chấp nhận? [đóng cửa]


123

Một đồng nghiệp của tôi nói rằng booleans là đối số phương thức không được chấp nhận . Chúng sẽ được thay thế bằng bảng liệt kê. Lúc đầu tôi không thấy có lợi ích gì, nhưng anh ấy đã cho tôi một ví dụ.

Điều gì dễ hiểu hơn?

file.writeData( data, true );

Hoặc là

enum WriteMode {
  Append,
  Overwrite
};

file.writeData( data, Append );

Bây giờ tôi đã nhận nó! ;-)
Đây chắc chắn là một ví dụ trong đó một phép liệt kê là tham số thứ hai làm cho mã dễ đọc hơn nhiều.

Vì vậy, ý kiến ​​của bạn về chủ đề này là gì?


7
Đây là một bài đọc rất thú vị, tôi sẽ thực hiện phương pháp này thường xuyên hơn.
Sara Chipps

hrm, tôi đã làm điều này trước đây, nhưng không bao giờ nhận ra mẫu thiết kế này tốt như thế nào. Vì vậy, enum đi trong tập tin?
Shawn

Enums chắc chắn có ý nghĩa hơn từ một PTC ngữ nghĩa. Một lưu ý khác, thật thú vị khi xem những gì một số lập trình viên đã nghĩ ra để xử lý logic mờ.
James P.

2
chỉ cần hỏi anh chàng chanh trên Adventure Time nếu điều này không được chấp nhận
ajax333221

Câu trả lời:


131

Boolean đại diện cho các lựa chọn "có / không". Nếu bạn muốn đại diện cho "có / không", sau đó sử dụng boolean, nó sẽ tự giải thích.

Nhưng nếu đó là sự lựa chọn giữa hai lựa chọn, không có lựa chọn nào rõ ràng là có hay không, thì đôi khi một enum có thể dễ đọc hơn.


3
Ngoài ra, tên phương thức phải rõ ràng về những gì đối số có hoặc không có nghĩa là void TurnLightOn (bool) cài đặt đúng sự thật hoặc có sẽ điều chỉnh ánh sáng.
simon

10
Mặc dù trong trường hợp này, tôi có lẽ nên có TurnLightOn () và TurnLight Offer (), tùy thuộc vào tình huống.
skaffman

14
"TurnLightOn (false)" có nghĩa là "không bật đèn"? Confusiong.
Jay Bazuzi

17
Thế còn setLightOn(bool).
Finbarr

10
Nhận xét muộn, nhưng @Jay Bazuzi: Nếu phương thức của bạn được gọi là TurnLightOn và bạn chuyển sai, bạn cũng có thể không gọi phương thức đó, chuyển sang sai nói không bật đèn. Nếu đèn đã sáng, điều đó không có nghĩa là tắt nó đi, điều đó có nghĩa là không bật nó lên ... Nếu bạn có một phương pháp 'TurnLight' một enum với 'On' và 'Off' có nghĩa, bật tắt ( Bật), bật đèn (Tắt). Tôi đồng ý với skaffman tho, tôi muốn có hai phương thức rõ ràng khác nhau, TurnLightOn () và TurnLightPack (). (BTW: Nội dung này được giải thích trong cuốn sách "Mã sạch" của chú Bobs)
Phill


32

Sử dụng một trong những mô hình tốt nhất vấn đề của bạn. Trong ví dụ bạn đưa ra, enum là một lựa chọn tốt hơn. Tuy nhiên, sẽ có những thời điểm khác khi một boolean tốt hơn. Điều này có ý nghĩa hơn với bạn:

lock.setIsLocked(True);

hoặc là

enum LockState { Locked, Unlocked };
lock.setLockState(Locked);

Trong trường hợp này, tôi có thể chọn tùy chọn boolean vì tôi nghĩ nó khá rõ ràng và không mơ hồ, và tôi khá chắc chắn rằng khóa của tôi sẽ không có nhiều hơn hai trạng thái. Tuy nhiên, lựa chọn thứ hai là hợp lệ, nhưng IMHO phức tạp không cần thiết.


2
trong ví dụ của bạn, tôi muốn có hai phương pháp. lock.lock () lock.release () và lock.Isset, nhưng tất cả phụ thuộc vào điều gì có ý nghĩa nhất đối với mã tiêu thụ.
Robert Paulson

3
Đó là một nhận xét công bằng, nhưng tôi nghĩ nó cũng minh họa điểm lớn hơn là có nhiều cách để mô hình hóa một vấn đề nhất định. Bạn nên sử dụng mô hình tốt nhất cho hoàn cảnh của mình và bạn cũng nên sử dụng các công cụ tốt nhất mà môi trường lập trình cung cấp để phù hợp với mô hình của bạn.
Jeremy Bourque

Tôi hoàn toàn đồng ý :), tôi chỉ bình luận về việc cung cấp mã giả cụ thể. Tôi đồng ý với câu trả lời của bạn.
Robert Paulson

14

Đối với tôi, không sử dụng boolean hay liệt kê là một cách tiếp cận tốt. Robert C. Martin nắm bắt điều này rất rõ ràng trong Mẹo sạch số 12 của mình: Loại bỏ các lập luận Boolean :

Các đối số Boolean lớn tiếng tuyên bố rằng hàm thực hiện nhiều hơn một điều. Họ đang bối rối và nên được loại bỏ.

Nếu một phương thức thực hiện nhiều hơn một điều, bạn nên viết hai phương thức khác nhau, ví dụ trong trường hợp của bạn: file.append(data)file.overwrite(data).

Sử dụng một bảng liệt kê không làm cho mọi thứ rõ ràng hơn. Nó không thay đổi bất cứ điều gì, nó vẫn là một đối số cờ.


7
Điều đó không có nghĩa là một hàm chấp nhận chuỗi ASCII có độ dài N có 128 ^ N hay không?
gièm pha

@d ERIC Đây có phải là một nhận xét nghiêm túc? Nếu có, bạn có thường viết mã nếu trên tất cả các giá trị có thể có của Chuỗi không? Có bất kỳ so sánh có thể với trường hợp của một đối số boolean?
Pascal Thivent

Tôi tin rằng chúng có thể chấp nhận được khi bạn đặt giá trị boolean bên trong một đối tượng. Một ví dụ hoàn hảo sẽ là setVisible(boolean visible) { mVisible = visible; }. Điều gì sẽ là một sự thay thế mà bạn đề nghị?
Brad

2
@Brad hiển thị () {mVisible = true} hide () {mVisible = false}
Oswaldo Acauan

@Oswaldo, trong khi vẫn đúng, tôi không nghĩ sẽ có hai phương thức khác nhau để gán một giá trị boolean cho các giá trị khác nhau. Bạn không có setIntToOne (), setIntToTwo () setIntToThree () phải không? Sẽ mơ hồ hơn một chút khi bạn chỉ có thể có hai giá trị có thể nhưng vì sự sạch sẽ, hãy sử dụng boolean trong trường hợp đó.
Brad

13

Tôi nghĩ rằng bạn gần như đã tự trả lời điều này, tôi nghĩ mục đích cuối cùng là làm cho mã dễ đọc hơn và trong trường hợp này, enum đã làm điều đó, IMO luôn luôn tốt nhất để xem mục tiêu cuối chứ không phải là quy tắc chăn, có thể nghĩ về nó nhiều hơn như một hướng dẫn tức là enums thường dễ đọc hơn mã hơn các bool chung, ints, v.v. nhưng sẽ luôn có ngoại lệ cho quy tắc.


13

Hãy nhớ câu hỏi Adlai Stevenson đặt ra cho đại sứ Zorin tại Liên Hợp Quốc trong cuộc khủng hoảng tên lửa Cuba ?

"Bạn đang ở trong phòng xử án của dư luận thế giới ngay bây giờ và bạn có thể trả lời có hoặc không . Bạn đã phủ nhận rằng [tên lửa] tồn tại và tôi muốn biết liệu tôi đã hiểu đúng về bạn chưa .... Tôi sẵn sàng chờ đợi cho câu trả lời của tôi cho đến khi địa ngục đóng băng, nếu đó là quyết định của bạn. "

Nếu cờ bạn có trong phương thức của bạn có tính chất như vậy mà bạn có thể xác định nó thành quyết định nhị phân và quyết định đó sẽ không bao giờ chuyển thành quyết định ba chiều hoặc n-way, hãy chọn boolean. Chỉ định: cờ của bạn được gọi là isXXX .

Đừng biến nó thành boolean trong trường hợp thứ gì đó là công tắc chế độ . Luôn có một chế độ nhiều hơn bạn nghĩ khi viết phương thức ở vị trí đầu tiên.

Tình trạng tiến thoái lưỡng nan một chế độ đã khiến Unix bị ám ảnh, trong đó các chế độ cấp phép có thể có của một tệp hoặc thư mục ngày nay có thể dẫn đến ý nghĩa kép của các chế độ tùy thuộc vào loại tệp, quyền sở hữu, v.v.


13

Có hai lý do khiến tôi gặp phải điều này là một điều tồi tệ:

  1. Bởi vì một số người sẽ viết các phương thức như:

    ProcessBatch(true, false, false, true, false, false, true);
    

    Điều này rõ ràng là xấu vì quá dễ để trộn lẫn các tham số và bạn không biết bằng cách xem nó là gì bạn đang chỉ định. Chỉ cần một bool không phải là quá xấu.

  2. Bởi vì kiểm soát luồng chương trình bằng một nhánh có / không đơn giản có thể có nghĩa là bạn có hai chức năng hoàn toàn khác nhau được kết hợp thành một theo cách thức tuyệt vời. Ví dụ:

    public void Write(bool toOptical);
    

    Thực sự, đây phải là hai phương pháp

    public void WriteOptical();
    public void WriteMagnetic();
    

    bởi vì mã trong đó có thể hoàn toàn khác nhau; họ có thể phải thực hiện tất cả các loại xử lý và xác nhận lỗi khác nhau hoặc thậm chí có thể phải định dạng dữ liệu đi khác nhau. Bạn không thể nói rằng chỉ bằng cách sử dụng Write()hoặc thậm chí Write(Enum.Optical)(mặc dù tất nhiên bạn có thể có một trong hai phương thức đó chỉ cần gọi các phương thức nội bộ WriteOptical / Mag nếu bạn muốn).

Tôi đoán nó chỉ phụ thuộc. Tôi sẽ không thỏa thuận quá nhiều về nó ngoại trừ # 1.


Điểm rất tốt! Thực tế, hai tham số boolean trong một phương thức trông rất tệ (trừ khi bạn may mắn có được các tham số được đặt tên, tất nhiên).
Yarik

Câu trả lời này có thể được hưởng lợi từ một số định dạng lại, mặc dù! ;-)
Yarik

7

Enums tốt hơn nhưng tôi sẽ không gọi params boolean là "không thể chấp nhận". Đôi khi chỉ đơn giản là ném một ít boolean vào và tiếp tục (nghĩ các phương thức riêng tư, v.v.)


chỉ làm cho phương thức rất mô tả để rõ ràng đúng hay đúng nghĩa là gì.
simon

6

Booleans có thể ổn trong các ngôn ngữ có tên tham số, như Python và Objective-C, vì tên có thể giải thích tham số đó làm gì:

file.writeData(data, overwrite=true)

hoặc là:

[file writeData:data overwrite:YES]

1
IMHO, writeData () là một ví dụ tồi về việc sử dụng tham số boolean, bất kể tham số có tên là hay không được hỗ trợ. Cho dù bạn đặt tên cho tham số như thế nào, ý nghĩa của giá trị Sai là không rõ ràng!
Yarik

4

Tôi sẽ không đồng ý rằng đó là một quy tắc tốt . Rõ ràng, Enum làm cho một mã rõ ràng hoặc dài dòng tốt hơn trong một số trường hợp, nhưng như một quy tắc, nó dường như vượt qua.

Trước tiên hãy để tôi lấy ví dụ của bạn: Các lập trình viên có trách nhiệm (và khả năng) viết mã tốt không thực sự bị nguy hiểm khi có tham số Boolean. Trong ví dụ của bạn, lập trình viên có thể đã viết giống như mã dài dòng bằng cách viết:

dim append as boolean = true
file.writeData( data, append );

hoặc tôi thích tổng quát hơn

dim shouldAppend as boolean = true
file.writeData( data, shouldAppend );

Thứ hai: Ví dụ Enum bạn đưa ra chỉ "tốt hơn" vì bạn đang vượt qua CONST. Nhiều khả năng trong hầu hết các ứng dụng ít nhất là một số nếu không phải hầu hết các tham số thời gian được truyền cho các hàm là VARIABLES. trong trường hợp đó, ví dụ thứ hai của tôi (đưa ra các biến có tên hay) tốt hơn nhiều và Enum sẽ mang lại cho bạn ít lợi ích.


1
Mặc dù tôi đồng ý rằng các tham số boolean được chấp nhận trong nhiều trường hợp, nhưng trong trường hợp ví dụ writeData () này, tham số boolean như ShouldAppend rất không phù hợp. Lý do rất đơn giản: không rõ ràng ý nghĩa của Sai là gì.
Yarik

4

Enums có một lợi ích nhất định, nhưng bạn không nên thay thế tất cả các booleans của mình bằng enums. Có nhiều nơi mà đúng / sai thực sự là cách tốt nhất để thể hiện những gì đang diễn ra.

Tuy nhiên, việc sử dụng chúng như các đối số phương pháp là một chút nghi ngờ, đơn giản chỉ vì bạn không thể nhìn thấy mà không đào sâu vào những gì họ có nghĩa vụ phải làm, vì chúng cho phép bạn xem những gì / sai sự thật thực sự có nghĩa là

Các thuộc tính (đặc biệt là với các công cụ khởi tạo đối tượng C # 3) hoặc các đối số từ khóa (a la ruby ​​hoặc python) là cách tốt hơn nhiều để đi đến nơi bạn sử dụng đối số boolean.

Ví dụ về C #:

var worker = new BackgroundWorker { WorkerReportsProgress = true };

Ví dụ về Ruby

validates_presence_of :name, :allow_nil => true

Ví dụ về Python

connect_to_database( persistent=true )

Điều duy nhất tôi có thể nghĩ về nơi một đối số phương thức boolean là điều đúng đắn phải làm là trong java, nơi bạn không có thuộc tính hoặc đối số từ khóa. Đây là một trong những lý do tôi ghét java :-(


4

Mặc dù sự thật là trong nhiều trường hợp, enum dễ đọc và dễ mở rộng hơn booleans, một quy tắc tuyệt đối rằng "booleans không được chấp nhận" là daft. Nó không linh hoạt và phản tác dụng - nó không chừa chỗ cho sự phán xét của con người. Chúng là một loại cơ bản được xây dựng trong hầu hết các ngôn ngữ vì chúng hữu ích - xem xét áp dụng nó cho các loại tích hợp khác: ví dụ: "không bao giờ sử dụng int làm tham số" sẽ trở nên điên rồ.

Quy tắc này chỉ là một câu hỏi về phong cách, không có tiềm năng cho lỗi hoặc hiệu suất thời gian chạy. Một quy tắc tốt hơn sẽ là "thích enum hơn booleans vì lý do dễ đọc".

Nhìn vào khung .Net. Booleans được sử dụng làm tham số trên khá nhiều phương thức. API .Net không hoàn hảo, nhưng tôi không nghĩ rằng việc sử dụng boolean làm tham số là một vấn đề lớn. Chú giải công cụ luôn cung cấp cho bạn tên của tham số và bạn cũng có thể xây dựng loại hướng dẫn này - điền vào các nhận xét XML của bạn về các tham số phương thức, chúng sẽ xuất hiện trong chú giải công cụ.

Tôi cũng nên nói thêm rằng có một trường hợp khi bạn nên cấu trúc lại booleans một cách rõ ràng - khi bạn có hai hoặc nhiều booleans trong lớp của bạn, hoặc trong các tham số phương thức của bạn, và không phải tất cả các trạng thái đều hợp lệ (ví dụ: không hợp lệ cả hai đều đúng).

Ví dụ, nếu lớp của bạn có các thuộc tính như

public bool IsFoo
public bool IsBar

Và đó là một lỗi để có cả hai cùng một lúc, những gì bạn thực sự có là ba trạng thái hợp lệ, được thể hiện tốt hơn như sau:

enum FooBarType { IsFoo, IsBar, IsNeither };

4

Một số quy tắc mà đồng nghiệp của bạn có thể tuân thủ tốt hơn là:

  • Đừng giáo điều với thiết kế của bạn.
  • Chọn những gì phù hợp nhất cho người dùng mã của bạn.
  • Đừng cố bash chốt hình ngôi sao vào mọi lỗ chỉ vì bạn thích hình dạng trong tháng này!

3

Boolean sẽ chỉ được chấp nhận nếu bạn không có ý định mở rộng chức năng của khung. Enum được ưa thích vì bạn có thể mở rộng enum và không phá vỡ các triển khai trước đó của lệnh gọi hàm.

Ưu điểm khác của Enum là dễ đọc hơn.


2

Nếu phương thức hỏi một câu hỏi như:

KeepWritingData (DataAvailable());

Ở đâu

bool DataAvailable()
{
    return true; //data is ALWAYS available!
}

void KeepWritingData (bool keepGoing)
{
   if (keepGoing)
   {
       ...
   }
}

đối số phương pháp boolean dường như có ý nghĩa hoàn hảo tuyệt đối.


Một ngày nào đó bạn sẽ cần thêm "tiếp tục viết nếu bạn có không gian trống", và sau đó bạn sẽ đi từ bool sang enum.
Ilya Ryzhenkov

Và sau đó, bạn sẽ có sự thay đổi đột phá, hoặc có quá tải lỗi thời, hoặc có thể là một cái gì đó giống như KeppWritingDataEx :)
Ilya Ryzhenkov

1
@Ilya hoặc có thể bạn sẽ không! Tạo một tình huống có thể trong đó không có hiện tại không tồn tại không phủ nhận giải pháp.
Jesse C. Choper

1
Jesse đúng. Lập kế hoạch cho một sự thay đổi như thế là ngớ ngẩn. Làm những gì có ý nghĩa. Trong trường hợp này, boolean vừa trực quan vừa rõ ràng. c2.com/xp/DoTheSimplestT BreathThatCouldPossizableWork.html
Công viên Derek

@Derek, trong trường hợp này, boolean thậm chí không cần thiết, bởi vì DataAv Available luôn trả về đúng :)
Ilya Ryzhenkov

2

Nó phụ thuộc vào phương pháp. Nếu phương thức thực hiện điều gì đó rất rõ ràng là đúng / sai thì nó vẫn ổn, ví dụ như bên dưới [mặc dù tôi không nói đây là thiết kế tốt nhất cho phương pháp này, đó chỉ là một ví dụ về việc sử dụng rõ ràng].

CommentService.SetApprovalStatus(commentId, false);

Tuy nhiên, trong hầu hết các trường hợp, chẳng hạn như ví dụ bạn đề cập, tốt hơn là sử dụng phép liệt kê. Có rất nhiều ví dụ trong .NET Framework, nơi quy ước này không được tuân theo, nhưng đó là do họ đã giới thiệu hướng dẫn thiết kế này khá muộn trong chu trình.


2

Nó làm cho mọi thứ rõ ràng hơn một chút, nhưng bắt đầu mở rộng ồ ạt sự phức tạp của các giao diện của bạn - trong một lựa chọn boolean tuyệt đối như nối thêm / ghi đè có vẻ như quá mức cần thiết. Nếu bạn cần thêm một tùy chọn khác (mà tôi không thể nghĩ ra trong trường hợp này), bạn luôn có thể thực hiện một bộ tái cấu trúc (tùy thuộc vào ngôn ngữ)


1
Điều gì về việc chuẩn bị như là một lựa chọn thứ ba có thể? ;-))
Yarik

2

Enums chắc chắn có thể làm cho mã dễ đọc hơn. Vẫn còn một vài điều cần chú ý (ít nhất là trong .net)

Vì lưu trữ cơ bản của enum là int, nên giá trị mặc định sẽ bằng 0, vì vậy bạn nên đảm bảo rằng 0 là mặc định hợp lý. (Ví dụ: cấu trúc có tất cả các trường được đặt thành 0 khi được tạo, vì vậy không có cách nào để chỉ định mặc định khác 0. Nếu bạn không có giá trị 0, bạn thậm chí không thể kiểm tra enum mà không truyền vào int phong cách xấu.)

Nếu enum của bạn là riêng tư đối với mã của bạn (không bao giờ được hiển thị công khai) thì bạn có thể dừng đọc tại đây.

Nếu enum của bạn được xuất bản theo bất kỳ cách nào đối với mã bên ngoài và / hoặc được lưu bên ngoài chương trình, hãy xem xét đánh số chúng một cách rõ ràng. Trình biên dịch sẽ tự động đánh số chúng từ 0, nhưng nếu bạn sắp xếp lại các enum của mình mà không cung cấp cho chúng các giá trị thì bạn có thể bị lỗi.

Tôi có thể viết hợp pháp

WriteMode illegalButWorks = (WriteMode)1000000;
file.Write( data, illegalButWorks );

Để chống lại điều này, bất kỳ mã nào sử dụng enum mà bạn không thể chắc chắn (ví dụ API công khai) cần kiểm tra xem enum có hợp lệ không. Bạn làm điều này thông qua

if (!Enum.IsDefined(typeof(WriteMode), userValue))
    throw new ArgumentException("userValue");

Nhắc nhở duy nhất Enum.IsDefinedlà nó sử dụng sự phản chiếu và chậm hơn. Nó cũng bị một vấn đề phiên bản. Nếu bạn cần kiểm tra giá trị enum thường xuyên, bạn sẽ tốt hơn nếu như sau:

public static bool CheckWriteModeEnumValue(WriteMode writeMode)
{
  switch( writeMode )
  {
    case WriteMode.Append:
    case WriteMode.OverWrite:
      break;
    default:
      Debug.Assert(false, "The WriteMode '" + writeMode + "' is not valid.");
      return false;
  }
  return true;
}

Vấn đề về phiên bản là mã cũ chỉ có thể biết cách xử lý 2 enum bạn có. Nếu bạn thêm giá trị thứ ba, Enum.IsDefined sẽ đúng, nhưng mã cũ không nhất thiết phải xử lý nó. Rất tiếc.

Thậm chí còn có nhiều điều thú vị hơn mà bạn có thể làm với [Flags]enums và mã xác nhận cho điều đó hơi khác một chút.

Tôi cũng lưu ý rằng đối với tính di động, bạn nên sử dụng lệnh gọi ToString()trên enum và sử dụng Enum.Parse()khi đọc lại. Cả hai ToString()Enum.Parse()cũng có thể xử lý [Flags]enum, vì vậy không có lý do gì để không sử dụng chúng. Nhắc bạn, đó là một cạm bẫy khác, bởi vì bây giờ bạn thậm chí không thể thay đổi tên của enum mà không có thể phá mã.

Vì vậy, đôi khi bạn cần cân nhắc tất cả những điều trên khi bạn tự hỏi mình Tôi có thể thoát khỏi chỉ với một bool không?


1

IMHO có vẻ như một enum sẽ là lựa chọn rõ ràng cho mọi tình huống có thể có nhiều hơn hai lựa chọn. Nhưng chắc chắn có những tình huống mà một boolean là tất cả những gì bạn cần. Trong trường hợp đó tôi sẽ nói rằng việc sử dụng một enum trong đó bool sẽ hoạt động sẽ là một ví dụ về việc sử dụng 7 từ khi 4 sẽ làm.


0

Booleans có ý nghĩa khi bạn có một chuyển đổi rõ ràng chỉ có thể là một trong hai điều (tức là trạng thái của bóng đèn, bật hoặc tắt). Ngoài ra, thật tốt khi viết nó theo cách rõ ràng những gì bạn đang vượt qua - ví dụ như ghi đĩa - không có bộ đệm, bộ đệm dòng hoặc đồng bộ - nên được thông qua như vậy. Ngay cả khi bạn không muốn cho phép viết đồng bộ ngay bây giờ (và do đó bạn bị giới hạn ở hai tùy chọn), bạn nên cân nhắc làm cho chúng dài dòng hơn cho mục đích biết những gì chúng làm ngay từ cái nhìn đầu tiên.

Điều đó nói rằng, bạn cũng có thể sử dụng Sai và Đúng (boolean 0 và 1) và sau đó nếu bạn cần thêm giá trị sau, hãy mở rộng hàm ra để hỗ trợ các giá trị do người dùng xác định (giả sử 2 và 3) và các giá trị 0/1 cũ của bạn sẽ chuyển qua cổng độc đáo, vì vậy mã của bạn không bị phá vỡ.


0

Đôi khi nó đơn giản hơn để mô hình hóa các hành vi khác nhau với tình trạng quá tải. Để tiếp tục từ ví dụ của bạn sẽ là:

file.appendData( data );  
file.overwriteData( data );

Cách tiếp cận này làm giảm nếu bạn có nhiều tham số, mỗi tham số cho phép một tập hợp tùy chọn cố định. Ví dụ: một phương thức mở tệp có thể có một số hoán vị của chế độ tệp (mở / tạo), truy cập tệp (đọc / ghi), chế độ chia sẻ (không / đọc / ghi). Tổng số cấu hình bằng với các sản phẩm của Cartesian trong các tùy chọn riêng lẻ. Đương nhiên trong những trường hợp như vậy nhiều quá tải là không phù hợp.

Enums có thể, trong một số trường hợp làm cho mã dễ đọc hơn, mặc dù việc xác thực giá trị enum chính xác trong một số ngôn ngữ (ví dụ C #) có thể khó khăn.

Thông thường một tham số boolean được thêm vào danh sách các tham số dưới dạng quá tải mới. Một ví dụ trong .NET là:

Enum.Parse(str);  
Enum.Parse(str, true); // ignore case

Quá tải thứ hai trở nên khả dụng trong phiên bản sau của .NET framework so với phiên bản đầu tiên.

Nếu bạn biết rằng sẽ chỉ có hai lựa chọn, một boolean có thể sẽ ổn. Enums có thể mở rộng theo cách không phá vỡ mã cũ, mặc dù các thư viện cũ có thể không hỗ trợ các giá trị enum mới để phiên bản không thể bị coi thường.


BIÊN TẬP

Trong các phiên bản mới hơn của C #, có thể sử dụng các đối số được đặt tên, IMO, có thể làm cho mã cuộc gọi rõ ràng hơn giống như cách mà enums có thể. Sử dụng ví dụ tương tự như trên:

Enum.Parse(str, ignoreCase: true);

0

Tôi đồng ý rằng Enums là cách tốt để đi, trong các phương pháp mà bạn có 2 tùy chọn (và chỉ có hai tùy chọn bạn có thể có khả năng đọc mà không cần enum.)

ví dụ

public void writeData(Stream data, boolean is_overwrite)

Yêu Enums, nhưng boolean cũng hữu ích.


0

Đây là một mục cuối trên một bài viết cũ, và đến tận trang này sẽ không có ai đọc nó, nhưng vì chưa ai nói nó cả ....

Một bình luận nội tuyến đi một chặng đường dài để giải quyết boolvấn đề bất ngờ . Ví dụ ban đầu đặc biệt khủng khiếp: hãy tưởng tượng cố gắng đặt tên cho biến trong phần khai báo hàm! Nó sẽ giống như

void writeData( DataObject data, bool use_append_mode );

Nhưng, vì lợi ích của ví dụ, hãy nói rằng đó là tuyên bố. Sau đó, đối với một đối số boolean không giải thích được, tôi đặt tên biến trong một nhận xét nội tuyến. Đối chiếu

file.writeData( data, true );

với

file.writeData( data, true /* use_append_mode */);

-1

Nó thực sự phụ thuộc vào bản chất chính xác của lập luận. Nếu nó không phải là có / không hoặc đúng / sai thì enum làm cho nó dễ đọc hơn. Nhưng với một enum, bạn cần kiểm tra đối số hoặc có hành vi mặc định chấp nhận được vì các giá trị không xác định của loại cơ sở có thể được thông qua.


-1

Việc sử dụng enum thay cho booleans trong ví dụ của bạn sẽ giúp phương thức gọi dễ đọc hơn. Tuy nhiên, đây là một thay thế cho mục mong muốn yêu thích của tôi trong C #, được đặt tên đối số trong các cuộc gọi phương thức. Cú pháp này:

var v = CallMethod(pData = data, pFileMode = WriteMode, pIsDirty = true);

sẽ hoàn toàn dễ đọc và sau đó bạn có thể làm những gì một lập trình viên nên làm, đó là chọn loại thích hợp nhất cho từng tham số trong phương thức mà không cần quan tâm đến nó trông như thế nào trong IDE.

C # 3.0 cho phép các đối số được đặt tên trong các hàm tạo. Tôi không biết tại sao họ không thể làm điều này bằng các phương pháp.


Một ý tưởng thú vị. Nhưng bạn sẽ có thể sắp xếp lại các tham số? Bỏ qua thông số? Làm thế nào trình biên dịch sẽ biết quá tải mà bạn đã ràng buộc nếu điều này là tùy chọn? Ngoài ra, bạn sẽ phải đặt tên cho tất cả các tham số trong danh sách?
Drew Noakes

-1

Giá trị Booleans true/ falsechỉ. Vì vậy, nó không rõ ràng những gì nó đại diện. Enumcó thể có tên có ý nghĩa, ví dụ OVERWRITE, APPENDvv Vì vậy, sự đếm được tốt hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.