Nhận giá trị int từ enum trong C #


1825

Tôi có một lớp gọi là Questions(số nhiều). Trong lớp này có một enum gọi là Question(số ít) trông như thế này.

public enum Question
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

Trong Questionslớp tôi có một get(int foo)hàm trả về một Questionsđối tượng cho điều đó foo. Có một cách dễ dàng để lấy giá trị nguyên ra khỏi enum để tôi có thể làm một cái gì đó như thế này Questions.Get(Question.Role)?


31
Đối với cách khác: cast-int-to-enum-in-c-sharp .
nawfal

11
Tôi biết tôi đến bữa tiệc muộn, nhưng thay vì xác định phương thức của bạn vì get(int foo)bạn có thể định nghĩa phương thức đó khi bạn get(Question foo)thực hiện phương thức của mình bên trong phương thức, bạn có thể gọi phương thức của mình làQuestions.Get(Question.Role)
Joe

Câu trả lời:


2354

Chỉ cần bỏ enum, vd

int something = (int) Question.Role;

Ở trên sẽ làm việc cho phần lớn các enum bạn thấy trong tự nhiên, như kiểu cơ bản mặc định cho một enum là int.

Tuy nhiên, như cecilphillip chỉ ra, enum có thể có các loại cơ bản khác nhau. Nếu một enum được khai báo là a uint, longhoặc ulong, thì nó nên được chuyển thành loại enum; ví dụ cho

enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};

bạn nên sử dụng

long something = (long)StarsInMilkyWay.Wolf424B;

23
@ Điều đó không đúng. Bạn có thể tạo Bảng liệt kê mà không cần truyền, không bắt buộc. và tôi chỉ gán số trong các trường hợp đặc biệt, hầu hết thời gian, tôi để nó làm giá trị mặc định. nhưng bạn có thể làm enum Test { Item = 1 }và thấy đó 1 == (int)Test.Itemlà bằng nhau.
Jaider

33
@Jaider (int)Test.ItemĐó là một diễn viên! () là toán tử cast rõ ràng.
Sinthia V

48
@Sinthia V anh ấy nói bạn có thể tạo nó mà không cần casting, điều đó đúng
Paul Ridgway

7
Nếu loại cơ bản cho enum Questionkhông intnhưng longdàn diễn viên này sẽ cắt giảm Rolegiá trị tích phân!
quay

1
Khi bạn chấp nhận Enummột tham số, bạn biết chỉ là một số giá trị tích phân có thể có mà bạn có thể nhận được. Mặt khác, nếu bạn chỉ đơn giản là một int, thì bạn phải xác nhận nếu đó intlà trong các giá trị được chấp nhận. Do đó, làm phức tạp mã. Bạn luôn có thể ghi đè chữ ký của mình như `` `public void MyMethod (int x) {// làm điều gì đó với x} public void MyMethod (Enum x) {this.MyMethod ((int) x); } `` ``
Nhận thức

307

Kể từ Enums thể được bất kỳ loại tách rời ( byte, int, short, vv), một cách mạnh mẽ hơn để có được giá trị không thể thiếu cơ bản của enum sẽ được tận dụng các GetTypeCodephương pháp kết hợp với các Convertlớp:

enum Sides {
    Left, Right, Top, Bottom
}
Sides side = Sides.Bottom;

object val = Convert.ChangeType(side, side.GetTypeCode());
Console.WriteLine(val);

Điều này sẽ làm việc bất kể loại tích phân cơ bản.


32
Kỹ thuật này đã chứng minh giá trị của nó đối với tôi khi xử lý một loại chung trong đó T: enum (thực ra là T: struct, IConvertible nhưng đó là một câu chuyện khác).
aboy021

1
Làm thế nào bạn sẽ sửa đổi điều này để in ra giá trị thập lục phân của bên? Ví dụ này cho thấy giá trị thập phân. Vấn đề là varloại đó object, vì vậy bạn cần bỏ hộp và nó trở nên lộn xộn hơn tôi muốn.
Đánh dấu Lakata

2
Tôi nghĩ bạn nên thay đổi ví dụ để object val = Convert...etccác vartrong ví dụ của bạn sẽ luôn luôn được object.
Lưới

2
@TimAbell Tất cả những gì tôi thực sự có thể nói là chúng tôi thấy rằng các trang aspx được biên dịch động (nơi bạn phải triển khai các tệp .cs đến máy chủ trực tiếp) đang gán các số nguyên khác nhau cho mỗi giá trị. Điều đó có nghĩa là các đối tượng được tuần tự hóa một máy, được khử lưu lượng với các giá trị khác nhau trên một máy khác và bị hỏng một cách hiệu quả (gây ra hàng giờ nhầm lẫn). Chúng tôi đã nêu ra nó với MS và tôi dường như nhớ lại rằng họ nói rằng các số nguyên được tạo tự động không được đảm bảo giống nhau khi được xây dựng trên các phiên bản khung khác nhau.
NickG

4
@TimAbell Trong một dịp khác, một nhà phát triển đã xóa một giá trị Enum lỗi thời / không sử dụng khiến tất cả các giá trị khác trong chuỗi bị loại bỏ. Do đó, các tiêu chuẩn mã hóa của chúng tôi hiện yêu cầu ID luôn được chỉ định rõ ràng, nếu không, việc thêm / xóa hoặc thậm chí tự động định dạng mã (ví dụ: sắp xếp theo thứ tự abc) sẽ thay đổi tất cả các giá trị gây ra hỏng dữ liệu. Tôi đặc biệt khuyên mọi người chỉ định rõ ràng tất cả các số nguyên Enum. Điều này cực kỳ quan trọng nếu chúng tương quan với các giá trị được lưu trữ bên ngoài (cơ sở dữ liệu).
NickG

199

Khai báo nó như là một lớp tĩnh có các hằng công khai:

public static class Question
{
    public const int Role = 2;
    public const int ProjectFunding = 3;
    public const int TotalEmployee = 4;
    public const int NumberOfServers = 5;
    public const int TopBusinessConcern = 6;
}

Và sau đó bạn có thể tham chiếu nó như là Question.Role, và nó luôn đánh giá một inthoặc bất cứ điều gì bạn định nghĩa nó là.


31
Tôi sẽ sử dụng static readonly intvì các hằng số được biên dịch thành các giá trị cứng của chúng. Xem stackoverflow.com/a/755693/492
CAD bloke

96
Giải pháp này thực sự không cung cấp lợi ích thực sự của các enum được gõ mạnh. Ví dụ, nếu tôi chỉ muốn truyền tham số GameState-enum cho một phương thức cụ thể, trình biên dịch không nên cho phép tôi chuyển bất kỳ biến int nào dưới dạng tham số.
Junc

12
@CADBloke chính xác là lý do tại sao bạn sẽ sử dụng constchứ không phải static readonlyvì mỗi lần bạn so sánh static readonlybạn đang thực hiện một cuộc gọi phương thức để nhận giá trị của biến trong khi constbạn đang so sánh trực tiếp hai loại giá trị.
blockloop

3
@ brettof86 Vâng, một const sẽ nhanh hơn, nếu giới hạn biên dịch sẽ không bao giờ là vấn đề thì tất cả đều tốt.
CAD bloke

2
@Zack Tôi đã không giải thích điều đó rất tốt, bởi compilation limitationý tôi là giá trị được mã hóa cứng khi bạn biên dịch nó để bất kỳ thay đổi nào đối với giá trị đó sẽ yêu cầu tất cả các hội đồng sử dụng nó cần phải được biên dịch lại. Tôi có xu hướng đồng ý với bạn về việc sử dụng vì việc thay đổi các giá trị sẽ có tác động sâu rộng.
CAD bloke

87
Question question = Question.Role;
int value = (int) question;

Sẽ có kết quả value == 2.


34
Câu hỏi biến tạm thời là không cần thiết.
Gishu

1
Vì vậy, một cái gì đó giống như Câu hỏi này.Get (Convert.ToInt16 (Câu hỏi. Ứng dụng))
jim

6
Bạn có thể chỉ cần đúc theo một trong hai hướng; điều duy nhất cần xem là enum không thi hành bất cứ điều gì (giá trị enum có thể là 288, mặc dù không có câu hỏi nào tồn tại với con số đó)
Marc Gravell

@jim: Không, chỉ cần bỏ giá trị: Câu hỏi.Get ((int) Câu hỏi. Ứng dụng);
Guffa

1
@Gishu Bạn có thể nói nó ... đáng nghi ngờ. ;)
Felix D.

79

Trên một lưu ý liên quan, nếu bạn muốn nhận intgiá trị từ System.Enum, sau đó đưa ra eở đây:

Enum e = Question.Role;

Bạn có thể dùng:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

Hai cái cuối cùng là xấu xí. Tôi thích cái đầu tiên.


1
Cái thứ hai là nhanh nhất mặc dù.
Johan B

1
Là một người đã quen sử dụng Mixins trong modding Minecraft, người thứ hai có vẻ như là người chiến thắng rõ ràng.
Sollace

40

Nó dễ hơn bạn nghĩ - một enum đã là một int. Nó chỉ cần được nhắc nhở:

int y = (int)Question.Role;
Console.WriteLine(y); // Prints 2

15
Nitpick: này enum đã là một int. Các enum khác có thể là các loại khác nhau - hãy thử "enum SmallEnum: byte {A, B, C}"
mqp

9
Hoàn toàn đúng. Tham chiếu C #: "Mỗi loại liệt kê có một loại cơ bản, có thể là bất kỳ loại tích phân nào ngoại trừ char."
Michael Petrotta

33

Thí dụ:

public Enum EmpNo
{
    Raj = 1,
    Rahul,
    Priyanka
}

Và trong mã phía sau để lấy giá trị enum:

int setempNo = (int)EmpNo.Raj; // This will give setempNo = 1

hoặc là

int setempNo = (int)EmpNo.Rahul; // This will give setempNo = 2

Enums sẽ tăng thêm 1 và bạn có thể đặt giá trị bắt đầu. Nếu bạn không đặt giá trị bắt đầu, nó sẽ được gán là 0 ban đầu.


6
Điều này thực sự biên dịch?
Peter Mortensen

Một cái gì đó là Raj cũng có thể là một Raul hay Priyanka? Giá trị của bạn xung đột và phải tăng gấp đôi thành duy nhất, ví dụ 0, 1, 2, 4, 8, v.v ... Đây là mối quan tâm cốt lõi của tôi với enums.
Timothy Gonzalez

@TimothyGonzalez thực sự chỉ đơn giản là đếm 1 nếu bạn không xác định rõ giá trị của chúng;)
derHugo

@derHugo tùy thuộc vào việc bạn giả sử các giá trị số là cơ sở 10 hay cơ sở 2.
Timothy Gonzalez

@TimothyGonzalez cũng không có nhiều để giả ... Tôi chỉ chỉ ra rằng theo mặc định họ chỉ cần đếm lên 1trong intngoại trừ bạn một cách rõ ràng xác định bằng cách khác
derHugo

28

Gần đây tôi đã chuyển đổi từ việc sử dụng enum trong mã của mình thay vì sử dụng các lớp với các hàm tạo được bảo vệ và các thể hiện tĩnh được xác định trước (nhờ Roelof - C # Đảm bảo các giá trị Enum hợp lệ - Phương thức Futureproof ).

Xét về vấn đề đó, dưới đây là cách tôi tiếp cận vấn đề này (bao gồm chuyển đổi ngầm sang / từ int).

public class Question
{
    // Attributes
    protected int index;
    protected string name;
    // Go with a dictionary to enforce unique index
    //protected static readonly ICollection<Question> values = new Collection<Question>();
    protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>();

    // Define the "enum" values
    public static readonly Question Role = new Question(2,"Role");
    public static readonly Question ProjectFunding = new Question(3, "Project Funding");
    public static readonly Question TotalEmployee = new Question(4, "Total Employee");
    public static readonly Question NumberOfServers = new Question(5, "Number of Servers");
    public static readonly Question TopBusinessConcern = new Question(6, "Top Business Concern");

    // Constructors
    protected Question(int index, string name)
    {
        this.index = index;
        this.name = name;
        values.Add(index, this);
    }

    // Easy int conversion
    public static implicit operator int(Question question) =>
        question.index; //nb: if question is null this will return a null pointer exception

    public static implicit operator Question(int index) =>        
        values.TryGetValue(index, out var question) ? question : null;

    // Easy string conversion (also update ToString for the same effect)
    public override string ToString() =>
        this.name;

    public static implicit operator string(Question question) =>
        question?.ToString();

    public static implicit operator Question(string name) =>
        name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase));


    // If you specifically want a Get(int x) function (though not required given the implicit converstion)
    public Question Get(int foo) =>
        foo; //(implicit conversion will take care of the conversion for you)
}

Ưu điểm của phương pháp này là bạn có được mọi thứ bạn có từ enum, nhưng mã của bạn giờ đã linh hoạt hơn rất nhiều, vì vậy bạn cần thực hiện các hành động khác nhau dựa trên giá trị của Question, bạn có thể đặt logic vào Questionchính nó (ví dụ như trong OO ưa thích thời trang) trái ngược với việc đưa ra nhiều tuyên bố tình huống trong toàn bộ mã của bạn để giải quyết từng tình huống.


NB: Trả lời cập nhật 2018-04-27 để sử dụng các tính năng C # 6; tức là biểu thức khai báo và định nghĩa cơ thể biểu thức lambda. Xem lịch sử sửa đổi cho mã gốc. Điều này có lợi ích làm cho định nghĩa ít dài dòng hơn; đó là một trong những phàn nàn chính về cách tiếp cận của câu trả lời này.


2
Tôi đoán đó là sự đánh đổi giữa các diễn viên rõ ràng và mã bạn phải viết để phá vỡ nó. Vẫn thích việc thực hiện chỉ ước nó không quá dài. +1
Lankymart

3
Tôi đã sử dụng một số loại lớp khác nhau có cấu trúc tương tự như thế này. Tôi thấy họ làm việc rất tuyệt vời khi cố gắng làm theo phương pháp "đừng để tôi trở thành một thằng ngốc sau này".
James Haug

20

Nếu bạn muốn lấy một số nguyên cho giá trị enum được lưu trữ trong một biến, mà kiểu đó sẽ là Question, để sử dụng ví dụ trong một phương thức, bạn có thể chỉ cần làm điều này tôi đã viết trong ví dụ này:

enum Talen
{
    Engels = 1, Italiaans = 2, Portugees = 3, Nederlands = 4, Duits = 5, Dens = 6
}

Talen Geselecteerd;    

public void Form1()
{
    InitializeComponent()
    Geselecteerd = Talen.Nederlands;
}

// You can use the Enum type as a parameter, so any enumeration from any enumerator can be used as parameter
void VeranderenTitel(Enum e)
{
    this.Text = Convert.ToInt32(e).ToString();
}

Điều này sẽ thay đổi tiêu đề cửa sổ thành 4, bởi vì biến GeselecteerdTalen.Nederlands. Nếu tôi thay đổi nó Talen.Portugeesvà gọi lại phương thức, văn bản sẽ thay đổi thành 3.


3
mã hóa bằng tiếng Hà Lan. trời ơi
WiseStrawberry

Thật không may, cách tiếp cận này mang lại hiệu suất kém khi bạn sử dụng nó nhiều hơn. Tôi đã thử nó trong một số mã của tôi và thời gian trôi qua, ứng dụng của tôi ngày càng chậm hơn, với việc sử dụng CPU ngày càng ít đi. Điều này ngụ ý rằng các chủ đề đang chờ đợi một cái gì đó - tôi giả sử một loại bộ sưu tập rác, có thể là do quyền anh tham số enum cho ToInt32 (). Bằng cách chuyển sang một int.Pude () đơn giản, tôi đã có thể loại bỏ hoàn toàn hiệu năng kém này và hiệu suất vẫn giữ nguyên cho dù mã chạy được bao lâu.
Greg

16

Để đảm bảo giá trị enum tồn tại và sau đó phân tích nó, bạn cũng có thể làm như sau.

// Fake Day of Week
string strDOWFake = "SuperDay";

// Real Day of Week
string strDOWReal = "Friday";

// Will hold which ever is the real DOW.
DayOfWeek enmDOW;

// See if fake DOW is defined in the DayOfWeek enumeration.
if (Enum.IsDefined(typeof(DayOfWeek), strDOWFake))
{
    // This will never be reached since "SuperDay"
    // doesn't exist in the DayOfWeek enumeration.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWFake);
}
// See if real DOW is defined in the DayOfWeek enumeration.
else if (Enum.IsDefined(typeof(DayOfWeek), strDOWReal))
{
    // This will parse the string into it's corresponding DOW enum object.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWReal);
}

// Can now use the DOW enum object.
Console.Write("Today is " + enmDOW.ToString() + ".");

14

Có thể tôi đã bỏ lỡ nó, nhưng có ai đã thử một phương pháp mở rộng chung đơn giản chưa?

Điều này làm việc tuyệt vời cho tôi. Bạn có thể tránh kiểu truyền trong API theo cách này nhưng cuối cùng nó dẫn đến hoạt động loại thay đổi. Đây là một trường hợp tốt để lập trình Roslyn để trình biên dịch tạo phương thức GetValue <T> cho bạn.

    public static void Main()
    {
        int test = MyCSharpWrapperMethod(TestEnum.Test1);

        Debug.Assert(test == 1);
    }

    public static int MyCSharpWrapperMethod(TestEnum customFlag)
    {
        return MyCPlusPlusMethod(customFlag.GetValue<int>());
    }

    public static int MyCPlusPlusMethod(int customFlag)
    {
        // Pretend you made a PInvoke or COM+ call to C++ method that require an integer
        return customFlag;
    }

    public enum TestEnum
    {
        Test1 = 1,
        Test2 = 2,
        Test3 = 3
    }
}

public static class EnumExtensions
{
    public static T GetValue<T>(this Enum enumeration)
    {
        T result = default(T);

        try
        {
            result = (T)Convert.ChangeType(enumeration, typeof(T));
        }
        catch (Exception ex)
        {
            Debug.Assert(false);
            Debug.WriteLine(ex);
        }

        return result;
    }
}

Có thể bởi vì (int) customFlag ít gõ tất cả xung quanh và thực hiện ít nhiều cùng một thứ?
Tim Keat

Re "Có thể tôi đã bỏ lỡ nó, nhưng có ai đã thử một phương pháp mở rộng chung đơn giản chưa?" : SixOThree đã nói " Thay vào đó hãy sử dụng một phương thức mở rộng "Bronek nói "Bạn có thể làm điều này bằng cách triển khai một phương thức mở rộng cho loại enum đã xác định của bạn" .
Peter Mortensen

13

Một cách nữa để làm điều đó:

Console.WriteLine("Name: {0}, Value: {0:D}", Question.Role);

Nó sẽ dẫn đến:

Name: Role, Value: 2

12
public enum QuestionType
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

... là một tuyên bố tốt.

Bạn phải truyền kết quả cho int như vậy:

int Question = (int)QuestionType.Role

Nếu không, loại vẫn còn QuestionType.

Mức độ nghiêm ngặt này là cách C #.

Một cách khác là sử dụng khai báo lớp thay thế:

public class QuestionType
{
    public static int Role = 2,
    public static int ProjectFunding = 3,
    public static int TotalEmployee = 4,
    public static int NumberOfServers = 5,
    public static int TopBusinessConcern = 6
}

Việc khai báo ít thanh lịch hơn, nhưng bạn không cần phải viết mã:

int Question = QuestionType.Role

Ngoài ra, bạn có thể cảm thấy thoải mái hơn với Visual Basic, phục vụ cho loại kỳ vọng này trong nhiều lĩnh vực.


11
int number = Question.Role.GetHashCode();

numbernên có giá trị 2.


GetHashCode là một cách để nhận giá trị từ mặt nạ chung Enum
ThanhLD

Lưu ý rằng đây chỉ là "hợp pháp" cho bool*, byte, ushort, int, và uint**. GetHashCode cho các loại khác sửa đổi giá trị, ví dụ như một số bithifts và xors. (* 1/0, ** tất nhiên được chuyển thành int). Nhưng tất cả trong tất cả chỉ không làm điều này trừ khi đó là mã riêng của bạn.
AnorZaken

10

Bạn có thể làm điều này bằng cách thực hiện một phương thức mở rộng cho loại enum đã xác định của bạn:

public static class MyExtensions
{
    public static int getNumberValue(this Question questionThis)
    {
        return (int)questionThis;
    }
}

Điều này giúp đơn giản hóa việc nhận giá trị int của giá trị enum hiện tại:

Question question = Question.Role;
int value = question.getNumberValue();

hoặc là

int value = Question.Role.getNumberValue();

5
Bronek, những gì bạn đã làm là tạo ra cú pháp không chính xác thông qua một phương thức mở rộng (không chung chung btw) mà thực sự mất nhiều thời gian hơn để viết. Tôi không thấy làm thế nào nó tốt hơn giải pháp ban đầu của Tetraneutron. Chúng ta đừng biến điều này thành một cuộc trò chuyện, sự giúp đỡ luôn được chào đón trong stackoverflow và mọi người ở đây đều ở đây để giúp đỡ. Xin hãy nhận xét của tôi như những lời chỉ trích mang tính xây dựng.
Benjamin Gruenbaum

2
Trước tiên, tại sao bạn lại xóa bình luận của tôi? Tôi không hiểu quyết định của bạn - có thể ai đó thông qua cộng đồng sẽ đồng ý với nhận xét của tôi. Thứ hai, giải pháp của tôi bao bọc ý kiến ​​của Tetraneutron và chính xác là nó dễ dàng và ít viết hơn vì Phương pháp mở rộng được đề xuất bởi IntelliSense. Vì vậy, tôi nghĩ rằng quyết định của bạn không phải là vô tư và đại diện. Tôi thấy nhiều câu trả lời tương tự trên Stack và không sao. Dù sao tôi cũng sử dụng giải pháp của mình và có thể một số người sẽ chọn giải pháp của tôi trong tương lai, nhưng những điểm tiêu cực này làm cho nó khó tìm hơn. Hầu hết tất cả đều đúng và không sao chép.
Bronek

3
@Bronek Nếu bạn không ping tôi, tôi không nhận được dấu hiệu nào cho thấy bạn đã trả lời. Tôi không xóa bình luận của bạn Tôi không có khả năng hoặc muốn làm như vậy. Có khả năng một mod đã xuất hiện và xóa nó - bạn có thể gắn cờ nó cho sự chú ý của người điều hành và hỏi tại sao hoặc tốt hơn - hãy hỏi về Meta Stack Overflow . Tôi có ý kiến ​​về giải pháp của bạn từ quan điểm lập trình hoàn toàn theo ý tôi - đây là ý kiến ​​dành cho việc bắt đầu, không cần phải xem nó là cá nhân.
Benjamin Gruenbaum

8

Sử dụng phương pháp mở rộng thay thế:

public static class ExtensionMethods
{
    public static int IntValue(this Enum argEnum)
    {
        return Convert.ToInt32(argEnum);
    }
}

Và việc sử dụng là một chút đẹp hơn:

var intValue = Question.Role.IntValue();

7
public enum Suit : int
{
    Spades = 0,
    Hearts = 1,
    Clubs = 2,
    Diamonds = 3
}

Console.WriteLine((int)(Suit)Enum.Parse(typeof(Suit), "Clubs"));

// From int
Console.WriteLine((Suit)1);

// From a number you can also
Console.WriteLine((Suit)Enum.ToObject(typeof(Suit), 1));

if (typeof(Suit).IsEnumDefined("Spades"))
{
    var res = (int)(Suit)Enum.Parse(typeof(Suit), "Spades");
    Console.Out.WriteLine("{0}", res);
}

bộ đồ - "10. (trò chơi bài) Mỗi ​​bộ gồm một bộ thẻ được phân biệt bằng màu sắc và / hoặc biểu tượng cụ thể, chẳng hạn như hình cầu, trái tim, kim cương hoặc câu lạc bộ của thẻ chơi Anglo, Tây Ban Nha và Pháp truyền thống."
Peter Mortensen

Một lời giải thích về mã mẫu sẽ theo thứ tự (bằng cách chỉnh sửa câu trả lời của bạn , không phải ở đây trong các bình luận).
Peter Mortensen

zero thường được dành riêng cho trạng thái unset / unkown trong enum, không bình thường để định nghĩa nó như thế
Chad Grant

6

Sử dụng:

Question question = Question.Role;
int value = question.GetHashCode();

Nó sẽ dẫn đến value == 2.

Điều này chỉ đúng nếu enum vừa vặn bên trong một int.


1
Điều này chỉ đúng nếu enum phù hợp với một intkhóa học, vì GetHashCodetrả về một số nguyên.
RB.

5

Vì enum có thể được khai báo với nhiều kiểu nguyên thủy, nên một phương thức mở rộng chung để bỏ bất kỳ loại enum nào có thể hữu ích.

enum Box
{
    HEIGHT,
    WIDTH,
    DEPTH
}

public static void UseEnum()
{
    int height = Box.HEIGHT.GetEnumValue<int>();
    int width = Box.WIDTH.GetEnumValue<int>();
    int depth = Box.DEPTH.GetEnumValue<int>();
}

public static T GetEnumValue<T>(this object e) => (T)e;

4

Sau đây là phương pháp mở rộng

public static string ToEnumString<TEnum>(this int enumValue)
{
    var enumString = enumValue.ToString();
    if (Enum.IsDefined(typeof(TEnum), enumValue))
    {
        enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
    }
    return enumString;
}

4

Hack yêu thích của tôi với en en int hoặc nhỏ hơn:

GetHashCode();

Cho một enum

public enum Test
{
    Min = Int32.MinValue,
    One = 1,
    Max = Int32.MaxValue,
}

Điều này,

var values = Enum.GetValues(typeof(Test));

foreach (var val in values)
{
    Console.WriteLine(val.GetHashCode());
    Console.WriteLine(((int)val));
    Console.WriteLine(val);
}

đầu ra

one
1
1
max
2147483647
2147483647
min
-2147483648
-2147483648

Tuyên bố từ chối trách nhiệm:

Nó không hoạt động cho enums dựa trên dài.


3

Giải pháp đơn giản nhất tôi có thể nghĩ đến là quá tải Get(int)phương thức như thế này:

[modifiers] Questions Get(Question q)
{
    return Get((int)q);
}

nơi [modifiers]thường có thể giống như đối với Get(int)phương pháp. Nếu bạn không thể chỉnh sửa Questionslớp hoặc vì một số lý do không muốn, bạn có thể quá tải phương thức bằng cách viết một phần mở rộng:

public static class Extensions
{
    public static Questions Get(this Questions qs, Question q)
    {
        return qs.Get((int)q);
    }
}

3

Ví dụ tôi muốn đề xuất "để lấy giá trị 'int' từ enum", là

public enum Sample
{
    Book = 1, 
    Pen = 2, 
    Pencil = 3
}

int answer = (int)Sample.Book;

Bây giờ câu trả lời sẽ là 1.



2

Hãy thử cái này thay vì chuyển enum thành int:

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}

2

Trong Visual Basic, nó phải là:

Public Enum Question
    Role = 2
    ProjectFunding = 3
    TotalEmployee = 4
    NumberOfServers = 5
    TopBusinessConcern = 6
End Enum

Private value As Integer = CInt(Question.Role)

3
Câu hỏi dành cho C #.
Ctrl S

2
Tiêu đề cho biết "Nhận giá trị int từ enum trong C #" .
Peter Mortensen

0

Tôi đã đưa ra phương pháp mở rộng này bao gồm các tính năng ngôn ngữ hiện tại. Bằng cách sử dụng động, tôi không cần biến phương thức này thành một phương thức chung và chỉ định kiểu giữ cho lệnh gọi đơn giản và nhất quán hơn:

public static class EnumEx
{
    public static dynamic Value(this Enum e)
    {
        switch (e.GetTypeCode())
        {
            case TypeCode.Byte:
            {
                return (byte) (IConvertible) e;
            }

            case TypeCode.Int16:
            {
                return (short) (IConvertible) e;
            }

            case TypeCode.Int32:
            {
                return (int) (IConvertible) e;
            }

            case TypeCode.Int64:
            {
                return (long) (IConvertible) e;
            }

            case TypeCode.UInt16:
            {
                return (ushort) (IConvertible) e;
            }

            case TypeCode.UInt32:
            {
                return (uint) (IConvertible) e;
            }

            case TypeCode.UInt64:
            {
                return (ulong) (IConvertible) e;
            }

            case TypeCode.SByte:
            {
                return (sbyte) (IConvertible) e;
            }
        }

        return 0;
    }

xin vui lòng không, bạn có thể thực hiện tất cả điều này trong một dòng Convert.Changetype (e, e.GetTypeCode ()) và lấy lại một đối tượng, không cần động lực học hoặc phương thức mở rộng
Chad Grant

Tôi sẽ không đồng ý với việc sử dụng Convert. Chỉ cần sử dụng một diễn viên sẽ dễ dàng hơn. Mục đích của tôi là có thể chuyển đổi bất kỳ enum nào thành giá trị của nó mà không cần sử dụng diễn viên. Điều này cho phép thay đổi wihtout loại enum phải thay đổi tất cả các phôi liên quan - nhưng khi nào thì điều này xảy ra?. Phương pháp mở rộng hoạt động chính xác. Tuy nhiên, tôi gặp vấn đề với nó, vì nó là động, trình kiểm tra không thể gõ kiểm tra (đối với toàn bộ câu lệnh rõ ràng) có nghĩa là kiểm tra kiểu xảy ra khi chạy - không phải là một giải pháp tốt. Tôi nghĩ rằng tôi sẽ quay trở lại diễn viên.
Jeff

1
Tôi đã không nói sử dụng nó trên diễn viên, chỉ là mã này là vô nghĩa và không làm được gì, thực sự làm cho vấn đề tồi tệ hơn. Tôi khuyên bạn nên xóa giải pháp này
Chad Grant
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.