2010-05-30 29 views
18

Tôi chỉ mới bắt đầu học C# và tôi đã trở thành khó khăn ở một cái gì đó rất cơ bản.Có sử dụng phạm vi thập phân trong một chuyển đổi không thể trong C#?

Đối với "ứng dụng" đầu tiên của tôi, tôi nghĩ rằng tôi muốn đi cho một cái gì đó đơn giản, vì vậy tôi quyết định cho một máy tính chỉ số BMI.

BMI được tính thành một loại thập phân mà tôi hiện đang cố gắng sử dụng trong câu lệnh chuyển đổi, nhưng không thể sử dụng số thập phân một phần trong một công tắc?

gì sẽ là giải pháp C# cho việc này:

  decimal bmi = calculate_bmi(h, w); 

      switch (bmi) { 
       case < 18.5: 
        bmi_description = "underweight."; 
        break; 
       case > 25: 
        bmi_description = "overweight"; 
       case > 30: 
        bmi_description = "very overweight"; 
       case > 40: 
        bmi_description = "extreme overweight"; 
        break; 
      } 
+0

Irony: http://stackoverflow.com/questions/2875533/what-features-do-you-want-to-see-in-net-5-c-5/2876114#2876114 – Dykam

Trả lời

14

Tuyên bố switch chỉ hỗ trợ integral types (liệt kê không được liệt kê nhưng có thể được sử dụng với câu lệnh switch vì chúng được hỗ trợ bởi loại tích phân) (chuỗi cũng được hỗ trợ như Changeling - xem chú thích để tham chiếu) và bình đẳng so sánh với các giá trị không đổi. Do đó, bạn phải sử dụng một số câu hỏi if.

if (bmi < 18.5M) 
{ 
    bmi_description = "underweight."; 
} 
else if (bmi <= 25) 
{ 
    // You missed the 'normal' case in your example. 
} 
else if (bmi <= 30) 
{ 
    bmi_description = "overweight"; 
} 
else if (bmi <= 40) 
{ 
    bmi_description = "very overweight"; 
} 
else 
{ 
    bmi_description = "extreme overweight"; 
} 

Bằng cách này, câu lệnh chuyển đổi của bạn hơi mệt vì bạn đang chuyển từ nhỏ hơn lớn hơn và sử dụng không bị gián đoạn. Tôi nghĩ rằng người ta chỉ nên sử dụng một loại so sánh để làm cho mã dễ hiểu hơn hoặc sắp xếp lại các kiểm tra và không sử dụng sự sụp đổ.

if (bmi < 18.5M) 
{ 
    bmi_description = "underweight."; 
} 
else if (bmi > 40) 
{ 
    bmi_description = "extreme overweight"; 
} 
else if (bmi > 30) 
{ 
    bmi_description = "very overweight"; 
} 
else if (bmi > 25) 
{ 
    bmi_description = "overweight"; 
} 
else 
{ 
    // You missed the 'normal' case in your example. 
} 
+0

Điều này hơi không chính xác. Nhà điều hành chuyển mạch cũng có thể sử dụng các chuỗi .. xem tại đây: http://msdn.microsoft.com/en-us/library/06tc147t%28VS.71%29.aspx –

+1

Cảm ơn bạn đã chỉ ra điều đó; đã cập nhật câu trả lời. –

+0

Cảm ơn bạn đã trợ giúp! Chữ M sau số thập phân 18,5 là những gì còn thiếu trong các giải pháp khác, vì vậy giải pháp này đã giải quyết nó cho tôi. Có bất kỳ "tên" cho những gì mà M làm, để tôi có thể làm một số đọc thêm về nó? – phobia

9

Đó không phải là có thể với switch báo cáo trong C#.
Lý do tại sao là bởi vì mỗi tuyên bố trường hợp yêu cầu một biểu thức liên tục sau nó.

Ngoài ra, mỗi giá trị chỉ được phép một lần và loại biểu thức phải khớp với loại trong switch của bạn. Trong trường hợp của bạn mà không phải là trường hợp vì bạn muốn có bool loại case báo cáo nhưng một số thập phân trong switch của bạn.

xem xét refactoring sử dụng một hàm helper thay vì:

//... 
decimal bmi = calculate_bmi(h, w); 
string bmi_description = get_description_for_bmi(bmi); 
//... 

string get_description_for_bmi(decimal bmi) 
{ 
    string desc; 
    if(bmi < 18.5m) 
     desc = "underweight"; 
    else if(bmi <= 25) 
     desc = "average";//You forgot this one btw 
    else if(bmi <= 30) 
     desc = "overweight"; 
    else if(bmi <= 40) 
     desc = "very overweight";  
    else 
     desc = "extreme overweight"; 

    return desc; 
} 

Tiếp tục đọc:

Không chỉ là những giá trị phạm vi không được phép nhưng biểu hiện không liên tục cũng không được phép.

Dưới đây là một ví dụ về một cái gì đó mà không thể:

bool b = true; 
bool y = false; 
switch (b) 
{ 
    case true: 
     break; 
    case y: 
     break; 
} 

Tuy nhiên điều này có thể:

bool b = true; 
const bool y = false; 
switch (b) 
{ 
    case true: 
     break; 
    case y: 
     break; 
} 
+0

Bạn có thể làm cho nó đơn giản hơn : bạn không cần phải kiểm tra 'bmi> 18.5', vì bạn đang ở trong' else'. Cũng vậy với các bài kiểm tra sau đây. 'if (bmi <= 18.5) ... else if (bmi <= 25) ... else if (bmi <= 30) ...' –

+0

@Thomas: Đúng cảm ơn, cố định. –

+0

Để * chính xác * khớp với hành vi của mã từ câu hỏi, nó phải <18,5 thay vì <= 18,5. –

0

Bạn cũng có thể sử dụng một số loại bộ sưu tập lưu trữ các giá trị cắt và mô tả. (Tôi không phải là chuyên gia về C# ... có thể là Dictionary<decimal,string>?) Lặp lại nó để tìm ra cái cuối cùng nhỏ hơn số bmi của bạn, và trả lại nhãn tương ứng của nó.

+0

vâng điều này nghe có vẻ giống như một giải pháp tốt đẹp ... bạn sẽ có thể lặp qua khóa hoặc giá trị khá dễ dàng bằng cách sử dụng một bộ sưu tập chung chung như từ điển. Nếu bạn cảm thấy đủ tự tin sử dụng một generic nếu không hãy thử sử dụng một điều tra viên như một enum và chuyển đổi trên các giá trị không đổi mà một biến enum hiện đang nắm giữ. – IbrarMumtaz

0

Từ khóa chuyển đổi hoạt động tốt với số thập phân. Đó là < và> điều đó khiến bạn gặp rắc rối.

+0

Chuyển đổi * không * hợp tác với số thập phân (bên cạnh đây là mới trong 4.0). –

1

phần đọc thêm của bạn,

switch chỉ có thể hoạt động với trên các giá trị hoặc các trường hợp trong đó giá trị đầu vào là một giá trị không đổi rằng việc chuyển đổi có thể tra cứu như một chỉ số và thực thi mã kèm theo định nghĩa bên trong một vụ án hay trường hợp điểm hoặc trường hợp nhãn, bất cứ điều gì tất cả có thể được sử dụng thay thế cho nhau.

Thay đổi y thành true trong ví dụ đầu tiên và nút gạt phải hoạt động trên 'b'.

Ví dụ thứ hai hoạt động vì trường hợp thứ hai đang chuyển đổi trên giá trị hằng số hoặc 'const'. Vì vậy, bạn đang đáp ứng các tiêu chí cơ bản hoặc những gì một chuyển đổi cần. Mặc dù nhiều người ở đây chắc chắn sẽ bảo bạn đừng viết mã như thế này. Bật một giá trị không đổi đơn giản và đảm bảo rằng công tắc của bạn chính xác phục vụ cho từng giá trị khác nhau mà biến được cung cấp của bạn có thể.

Hãy thử sử dụng một enum để làm cho mã của bạn rơi phù hợp với tiêu chuẩn. Net thực hành mã hóa nhận xét này cũng rơi vào dòng với đảm bảo bạn không nhận bất kỳ thói quen xấu nếu muốn thực hiện một sự nghiệp này ???

HÃY NHỚ: bạn có thể sử dụng enum và thiết lập để sử dụng giá trị thập phân dưới dạng thập phân là loại giá trị để đáp ứng tiêu chí của yêu cầu enum. Vì enum được định nghĩa trong khung .Net dưới dạng một loại giá trị nên chỉ các loại giá trị như kiểu số dựa trên mới có thể được thiết lập để tạo kiểu enum trong các lớp mã tùy chỉnh yuor. Đơn giản chỉ cần đính kèm mỗi giá trị với một tên hoặc một số loại như bạn đã sử dụng ở trên, như trên trọng lượng và vv và đảm bảo mỗi mục trong enum có một thứ tự hợp lý cho nó. tức là các mục nhập có giá trị thập phân có định nghĩa rõ ràng về việc đi lên hoặc xuống. Khi enum của bạn được thiết lập, hãy tạo một biến kiểu enum mà bạn vừa tạo và sau đó cung cấp biến này cho switch của bạn.

Học tập thú vị.

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