2012-08-16 30 views
15

Câu hỏi này liên quan đến đúc enums trong phương pháp chungC# Đúc với các đối tượng để enums

Với một enum

public enum Crustaceans 
{ 
    Frog = 1, 
    Toad = 4 
} 

tôi có thể tạo ra một thể hiện của enum của tôi chỉ đơn giản là đủ

short val = 4; 
Crustaceans crusty = (Crustaceans) val; 

Tuy nhiên, nếu

short val = 4; 
object obj = (object) val; 
Crustaceans crusty = (Crustaceans)obj; 

một ngoại lệ thời gian chạy được ném cố gắng để thực hiện việc khởi tạo của giòn.

Bất cứ ai có thể giải thích lý do tại sao điều này xảy ra và lý do tại sao việc lập một điều như vậy là không hợp pháp.

Không phải là tôi thực sự muốn làm điều này, nhưng tôi cam qua một vấn đề khi cố gắng để có được một cái gì đó tương tự xảy ra với generics và hiệu quả đó là những gì đang xảy ra dưới bìa. tức là

public T dosomething<T>(short val) where T : new() 
{ 
    T result = (T)(object) val; 
    return result; 
} 

Vì vậy, những gì tôi đang cố gắng làm là có một chức năng chung mà làm việc với enums và phi enums (không quá quan trọng, nhưng sẽ là tốt đẹp) có thể được thiết lập để một giá trị ngắn mà không ném một ngoại lệ và thực sự khởi tạo giá trị enum chính xác.

+21

Nó sẽ được ra khỏi dòng để chỉ ra rằng Frog và Toad không phải là động vật giáp xác?:) – JTMon

+1

bản sao có thể có của [Tại sao tôi không thể bỏ hộp số dưới dạng số thập phân?] (Http://stackoverflow.com/questions/1085097/why-cant-i-unbox-an-int-as-a-decimal) –

+2

@sweetfa: trong khi câu hỏi tôi chỉ ra giao dịch với int so với thập phân và không enums, nó giải thích hành vi (có liên quan đến boxing và unboxing). Đặc biệt, câu trả lời được chấp nhận đề cập đến một bài viết của Eric Lippert: "[Đại diện và danh tính] (http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx) ", điều này giải thích chi tiết này. –

Trả lời

30

Something như này có lẽ sẽ giúp bạn:

public T dosomething<T>(object o) 
{ 
    T enumVal= (T)Enum.Parse(typeof(T), o.ToString()); 
    return enumVal; 
} 

Nhưng điều này sẽ chỉ làm việc với enums, vì lý do rõ ràng của việc sử dụng Enum.Parse(..)

Và sử dụng này như thế nào, ví dụ:

object o = 4; 
dosomething<Crustaceans>(o); 

Điều đó sẽ trả về Toad trong trường hợp của bạn.

+1

Điều đó có thể được cố định bằng cách bao quanh mã với một kiểm tra cho nó là một enum hoặc một int như vậy nếu (T là enum) –

+0

Phiên bản cải tiến (?): công khai T dosomething (đối tượng o) { var enumType = typeof (T); nếu (! EnumType.IsEnum) ném ArgumentException mới ("Không phải là enum"); return (T) Convert.ChangeType (o, enumType); } – osexpert

-1

Có những trường hợp bạn không thể sử dụng Generics (như trong Bộ chuyển đổi WPF khi bạn nhận được giá trị là object). Trong trường hợp này, bạn không thể truyền tới int vì loại enum có thể không phải là int. Đây là một cách tổng quát để làm điều đó mà không có Generics. Các ví dụ được đưa ra bên trong một WPF Converter, nhưng mã bên trong là chung:

using System; 
using System.Windows; 
using System.Windows.Data; 

. 
. 
. 

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
{ 
    var enumType = value.GetType(); 
    var underlyingType = Enum.GetUnderlyingType(enumType); 
    var numericValue = System.Convert.ChangeType(value, underlyingType); 
    return numericValue; 
} 
0

Bởi giá trị enum mặc định chữ số có type = int. Trong mã của bạn, bạn muốn truyền giá trị có loại ngắn thành loại enum. Đối với điều đó, bạn phải đặt loại ngắn thành giá trị enum của bạn. Điều này sẽ làm việc:

public enum Crustaceans : short // <-- 
{ 
    Frog = 1, 
    Toad = 4 
} 

short @short = 1; 
object @object = @short; 

var @enum = (Crustaceans)@object; // @enum = Crustaceans.Frog 

nếu bạn không muốn thay đổi các giá trị enum mặc định gõ

public enum Crustaceans 
{ 
    Frog = 1, 
    Toad = 4 
} 

object @object = Crustaceans.Frog; 

var @enum = (Crustaceans)@object; // @enum = Crustaceans.Frog 

hoặc

public enum Crustaceans 
{ 
    Frog = 1, 
    Toad = 4 
} 

int @integer= 1; 

var @enum = (Crustaceans)@integer; // @enum = Crustaceans.Frog 
Các vấn đề liên quan