2011-01-18 40 views
25

Sử dụng phương pháp mở rộng, chúng ta có thể tạo phương thức chuyển đổi enum thành kiểu dữ liệu khác như chuỗi, int bằng cách tạo các phương thức mở rộng ToInt(), ToString(), v.v ...Enum từ chuỗi, int, v.v.

Tôi tự hỏi cách triển khai theo cách khác, ví dụ: FromInt(int), FromString(string), v.v. Theo như tôi biết tôi không thể tạo phương thức mở rộng MyEnum.FromInt() (tĩnh). Vậy cách tiếp cận có thể cho điều này là gì?

+6

Bạn thực hiện phương thức tiện ích mở rộng trên 'int' và' string', không phải 'enum' ... – Oded

+1

sẽ không phải là loại ô nhiễm 'int' và' string' vì chúng được sử dụng nhiều và hầu như không liên quan đến enum của tôi? –

+0

Phương thức như vậy (như ToEnum <> bên dưới) sẽ là mục đích chung (gần như ToString(), gần như). –

Trả lời

32

Tôi sẽ tránh gây ô nhiễm int hoặc chuỗi với các phương pháp mở rộng cho enums, thay vào đó một lớp trợ giúp tĩnh cũ tốt có thể theo thứ tự.

public static class EnumHelper 
{ 
    public static T FromInt<T>(int value) 
    { 
     return (T)value; 
    } 

    public static T FromString<T>(string value) 
    { 
    return (T) Enum.Parse(typeof(T),value); 
    } 
} 
+3

'TừInt' không biên dịch cho tôi, _Cannot chuyển đổi loại 'int' thành 'T'_? – Cel

+0

'T' là enum? Nó là một enum int? – Jamiec

+1

Tôi thậm chí không gọi nó và biên soạn không thành công - tôi đã làm việc này để thay thế: 'public static T ToEnum (giá trị int này) { return (T) Enum.Parse (typeof (T), value.ToString ()); } ' – Cel

0

Bạn có thể tạo phương thức mở rộng trên int và chuỗi.

Hoặc tạo phương pháp tĩnh trên một số lớp tĩnh khác. Có lẽ một cái gì đó giống như EnumHelper.FromInt (int).

Nhưng tôi sẽ đặt ra một câu hỏi: Tại sao bạn muốn chuyển đổi thành chuỗi hoặc int? Nó không phải như thế nào bạn normaly làm việc với enumerables, ngoại trừ có thể serialization. Nhưng điều đó nên được xử lý bởi một số loại cơ sở hạ tầng, không phải mã của riêng bạn.

+0

trả lời câu hỏi của bạn: Tôi đang tạo một trình bao bọc xung quanh nhiều thư viện. Họ không có quy ước tương tự về một số chuỗi, vì vậy tôi cố gắng tạo ra một enum để họ sẽ có cùng một quy ước. –

4

tại sao bạn muốn sử dụng phương pháp extIstion FromInt so với chỉ truyền nó?

MyEnum fromInt; 
if(Enum.IsDefined(typeof(MyEnum), intvalue)) 
{ 
    fromInt = (MyEnum) intvalue; 
} 
else 
{ 
    //not valid 
} 

cách khác, cho các chuỗi, bạn có thể sử dụng Enum.TryParse

MyEnum fromString; 
if (Enum.TryParse<MyEnum>(stringvalue, out fromString)) 
{ 
    //succeeded 
} 
else 
{ 
    //not valid 
} 
+0

Nếu stringvalue và intvalue không giống với giá trị cơ bản thì sao? –

+0

Tôi không nhận được những gì bạn đang nói. Bạn có hỏi những gì xảy ra trong chuỗi hoặc int không đại diện cho bất kỳ giá trị enum nào không? – RedDeckWins

+0

có. Nói cách khác, tôi không thể sử dụng Parse hoặc đúc –

19

Bạn có thực sự cần những phương pháp mở rộng?

MyEnum fromInt = (MyEnum)someIntValue; 
MyEnum fromString = (MyEnum)Enum.Parse(typeof(MyEnum), someStringValue, true); 

int intFromEnum = (int)MyEnum.SomeValue; 
string stringFromEnum = MyEnum.SomeValue.ToString(); 
6

Một cách khác xung quanh sẽ có thể ... cách khác xung quanh;) Mở rộng int và chuỗi với phương pháp khuyến nông chung sẽ diễn như tham số kiểu loại của một enum:

public static TEnum ToEnum<TEnum>(this int val) 
{ 
    return (TEnum) System.Enum.ToObject(typeof(TEnum), val); 
} 

public static TEnum ToEnum<TEnum>(this string val) 
{ 
    return (TEnum) System.Enum.Parse(typeof(TEnum), val); 
} 

Cách sử dụng:

var redFromInt = 141.ToEnum<System.Drawing.KnownColor>(); 
var redFromString = "Red".ToEnum<System.Drawing.KnownColor>(); 

Rất tiếc, không có ràng buộc chung cho Enums, vì vậy chúng tôi phải kiểm tra loại TEnum trong thời gian chạy; để đơn giản hóa, chúng tôi sẽ để lại xác minh đó cho các phương thức Enum.ToObjectEnum.Parse.

+0

Tôi thích rằng đây là một phương pháp có quá tải khác nhau. –

2

Bạn có thể làm:

public static class EnumExtensions 
{ 
    public static Enum FromInt32(this Enum obj, Int32 value) 
    { 
     return (Enum)((Object)(value)); 
    } 

    public static Enum FromString(this Enum obj, String value) 
    { 
     return (Enum)Enum.Parse(obj.GetType(), value); 
    } 
} 

Hoặc:

public static class Int32Extensions 
{ 
    public static Enum ToEnum(this Int32 obj) 
    { 
     return (Enum)((Object)(obj)); 
    } 
} 

public static class StringExtensions 
{ 
    public static Enum ToEnum(this Enum obj, String value) 
    { 
     return (Enum)Enum.Parse(obj.GetType(), value); 
    } 
} 
3

Một cách tiếp cận (đối với phần chuỗi các câu hỏi của bạn):

/// <summary> 
/// Static class for generic parsing of string to enum 
/// </summary> 
/// <typeparam name="T">Type of the enum to be parsed to</typeparam> 
public static class Enum<T> 
{ 
    /// <summary> 
    /// Parses the specified value from string to the given Enum type. 
    /// </summary> 
    /// <param name="value">The value.</param> 
    /// <returns></returns> 
    public static T Parse(string value) 
    { 
     //Null check 
     if(value == null) throw new ArgumentNullException("value"); 
     //Empty string check 
     value = value.Trim(); 
     if(value.Length == 0) throw new ArgumentException("Must specify valid information for parsing in the string", "value"); 
     //Not enum check 
     Type t = typeof(T); 
     if(!t.IsEnum) throw new ArgumentException("Type provided must be an Enum", "T"); 

     return (T)Enum.Parse(typeof(T), value); 
    } 
} 

(một phần lấy cảm hứng từ: http://devlicious.com/blogs/christopher_bennage/archive/2007/09/13/my-new-little-friend-enum-lt-t-gt.aspx)