2009-08-13 19 views
30

tôi đã xác định một C# enum nhưLàm cách nào tôi có thể sử dụng giá trị chuỗi của giá trị enum C# trong tuyên bố trường hợp?

public enum ORDER 
{ 
    ... 
    unknown, 
    partial01, 
    partial12, 
    partial23, 
} 

và có thể sử dụng giá trị của nó như là một chuỗi như trong:

  string ss = ORDER.partial01.ToString(); 

Tuy nhiên khi tôi cố gắng sử dụng nó trong một tuyên bố trường hợp nó không biên dịch:

string value = ... 
switch (value) 
{ 
    case null: 
     break; 
    case "s": 
     // OK 
     break; 
    case ORDER.partial01.ToString(): 
     // compiler throws "a constant value is expected" 

     break; 
    ... 

Tôi nghĩ rằng enums là hằng số. Làm thế nào để tôi có được điều này?

(Tôi không thể phân tích giá trị thành một enum như một số các giá trị nằm ngoài phạm vi)

Trả lời

21

Các enum là một hằng số, nhưng kết quả của ToString() thì không. Theo như trình biên dịch có liên quan, nó là một giá trị động. Bạn có thể cần phải chuyển đổi trường hợp chuyển đổi của mình thành một loạt các câu lệnh if/else

41

Chuyển đổi chuỗi trong chuyển đổi thành giá trị enum.

(ORDER)Enum.Parse(typeof(ORDER), value, true); 
+0

Điều đó sẽ không xử lý so sánh null, nhưng mà trường hợp cạnh thể được xử lý bên ngoài tuyên bố trường hợp. –

+0

giá trị chuỗi = null; // "partial01"; ĐẶT HÀNG? order = value == null? null: (ORDER?) Enum.Parse (typeof (ORDER), giá trị, true); –

2

Giá trị enum là hằng số, nhưng bạn đang cố gắng sử dụng kết quả của phương thức (ORDER.partial01.ToString()), không phải là hằng số.

Tùy chọn tốt nhất, theo ý kiến ​​của tôi, sẽ chỉ chuyển đổi xung quanh thành sử dụng if/else if/else statements, thay vì switch. Điều này sẽ cho phép bạn sử dụng logic mà bạn mong muốn.

Hoặc, nếu bạn chuyển chuỗi của mình thành giá trị enum, bạn có thể bật trực tiếp các giá trị enum. Tuy nhiên, bạn không thể bật enum + null + các chuỗi khác trong một chuyển đổi.

+0

Bạn có thể bật null nếu bạn sử dụng ORDER? ... không phải là dây. –

2

Không thể bạn chỉ cần thay vì nói

case "partial01": 

?

+2

Sau đó, bạn sẽ khó mã hóa và nhân bản các giá trị trong Enum. Điều đó có thể xấu xí khá nhanh. – MrGreggles

1

enums là hằng số nhưng ToString() là hàm trả về giá trị. dựa trên cá thể của đối tượng enum mà nó đang được gọi.

Đó là hai câu lệnh:

ORDER.partial01.ToString() 
ORDER.partial02.ToString() 

gọi hàm tương tự nhưng trả về hai giá trị khác nhau, do đó gọi hàm ToString() trong đó tự không phải là một giá trị không đổi.

1

Đây không phải là một giá trị tĩnh như xa như các trình biên dịch có liên quan, vì nó là một lời gọi hàm:

ORDER.partial01.ToString() 

Vì vậy, bạn không thể sử dụng nó như là một sự so sánh trong một tuyên bố như vậy. Tuy nhiên, bạn chỉ có thể thực hiện việc này:

case "partial01" 

Điều đó có hiệu quả, vì giá trị enum và chuỗi giống hệt nhau.

28

Để thay thế cho việc sử dụng if .. else, trước tiên bạn có thể chuyển đổi chuỗi của mình thành số enum.Nó có lẽ sẽ không có ý nghĩa nhiều nếu số lượng tùy chọn là nhỏ mặc dù:

if (Enum.IsDefined(typeof(ORDER), value)) 
{ 
    switch ((ORDER)Enum.Parse(typeof(ORDER), value) 
    { 
     case ORDER.partial01: 
      // ... 
      break; 
     case ORDER.partial12: 
      // etc 
    } 
} 
else 
{ 
    // Handle values not in enum here if needed 
} 

* thở dài * nếu chỉ được có một built-in T Enum.Parse<T>(string value), và một phiên bản TryParse :)

+4

quảng cáo là một 'Enum.TRyParse (giá trị chuỗi, kết quả T ra)' http://msdn.microsoft.com/en-us/library/dd783499.aspx (nó là v4.5) do đó không có sẵn tại thời gian viết bài) –

+0

chuyển ((ORDER) Enum.Parse (typeof (ORDER), giá trị) bỏ lỡ một kết thúc ")" – Enrico

9

Bạn thiết kế điều này như là một enum cho một lý do, nhưng bạn không thực sự làm cho việc sử dụng nó như là một enum. Tại sao bạn lấy giá trị enum và chuyển đổi nó thành một chuỗi để sau đó sử dụng trong chuyển đổi thay vì chỉ đơn giản bằng cách sử dụng enum?

Bạn đã nói rằng bạn không thể phân tích cú pháp này trong một enum vì một số giá trị nằm ngoài phạm vi enum. Câu hỏi đặt ra là, "Tại sao?" Điểm có enum là gì nếu bạn cho phép các giá trị không được xác định? Bạn muốn điều gì xảy ra khi bạn nhận được một giá trị không được xác định? Nếu đó là điều tương tự cho bất kỳ giá trị không xác định nào thì bạn có thể sử dụng trường hợp mặc định. Nếu không, bạn có thể bao gồm các trường hợp bổ sung khớp với biểu diễn dạng số.

Nếu bạn thực sự nhận được chuỗi lại, thì có thể bạn không muốn sử dụng enum. Thay vào đó bạn muốn tạo một lớp tĩnh công cộng có chứa các hằng số chuỗi công khai, sau đó bạn có thể sử dụng nó trong công tắc của mình. Bí quyết ở đây là việc đánh giá sẽ được thực hiện theo cách nhạy cảm.

public static class Order 
{ 
    public const string Unknown = "Unknown"; 
    public const string Partial01 = "Partial01"; 
    public const string Partial12 = "Partial12"; 
    public const string Partial23 = "Partial23"; 
} 

string value = Order.Partial01 
switch (value) 
{ 
    case Order.Partial01: 
     break; 

    default: 
     // Code you might want to run in case you are 
     // given a value that doesn't match. 
     break; 
} 

(Bạn cũng có thể muốn để làm sạch vỏ của bạn.)

+0

có những lúc chỉ có các giá trị enum được kiểm tra và các lần khác khi phạm vi giá trị rộng hơn có liên quan . Tôi đồng ý nó có lẽ là một thiết kế lộn xộn và nó có thể biến mất sau này. –

+0

@ peter.murray.rust: Bạn thực sự nhận được loại giá trị nào?Bạn luôn nhận được giá trị dưới dạng chuỗi hoặc là số? Nếu đó là số, hãy giữ enum, bật giá trị ** dưới dạng enum ** và có trường hợp mặc định hoặc các trường hợp được gắn nhãn khác khớp với giá trị "bổ sung" để thực hiện công việc phù hợp. Nếu đó là chuỗi, sau đó đi với cách tiếp cận tôi đã cho thấy và có một lớp tĩnh giữ các biểu diễn chuỗi. Bạn vẫn có thể thêm các trường hợp được gắn nhãn khác khớp với các giá trị "bổ sung". Tóm lại, một enum thực sự chỉ hữu ích nếu bạn muốn cung cấp các giá trị số "thân thiện" hoặc tên có ý nghĩa. –

4

Như Thorarin chỉ ra, câu lệnh if switch của bạn có thể chứa chỉ enum trường hợp, chuyển đổi của bạn string một enum đầu tiên. Ít nhất là của .Net framework 4, bạn có thể sử dụng phương pháp Enum.TryParse()<TEnum> theo quy định here và làm điều gì đó như:

ORDER orderEnum = ORDER.unknown; 
Enum.TryParse<ORDER>(value, out orderEnum); 

switch (orderEnum) 
{ 
    case ORDER.unknown: 
     // perhaps do something to deal with cases not matching 
     // to known enum values, based on the string value 
     break; 
    case ORDER.partial01: 
    case ORDER.partial12: 
    case ORDER.partial23: 
     // map value to known cases, etc. 
     break; 
} 
27

Kể từ C# 6, bạn có thể sử dụng: case nameof(SomeEnum.SomeValue):

Nameof được đánh giá tại thời gian biên dịch, chỉ đơn giản là một chuỗi khớp với tên (không đủ điều kiện) của biến, loại hoặc thành viên đã cho. Đương nhiên, nó thay đổi ngay khi bạn nên đổi tên tùy chọn enum.

+1

Tuyệt vời. Tôi muốn sử dụng giá trị chuỗi của enum tại thời gian biên dịch (trong một thuộc tính) và điều này giải quyết nó cho tôi. – dubbreak

0

chỉ đơn giản là bạn có thể định nghĩa một biến toàn cầu

static ORDER orderstr; 

bây giờ bạn có thể thiết lập giá trị của orderstr bất cứ nơi nào trong trang

public enum ORDER 
{ 
    unknown, 
    partial01, 
    partial12, 
    partial23, 
} 

switch (orderstr) 
{ 
    case Order.Partial01: 
     break; 
    default: 
     break; 
} 
Các vấn đề liên quan