سؤال

أرغب في إنشاء طريقة عامة لتحويل أي نظام مشتق حسب القيمة الصحيحة المقابلة، دون صب ويفضل أن يكون تحليل سلسلة.

على سبيل المثال، ما أريده هو شيء مثل هذا:

// Trivial example, not actually what I'm doing.
class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        (int)anEnum;
    }
}

ولكن هذا لا يبدو للعمل. تقارير إعادة البحث التي لا يمكنك إلقاء التعبير عن النوع "system.enum" لكتابة "int".

الآن لقد جئت مع هذا الحل ولكني أفضل أن يكون لديك شيء أكثر كفاءة.

class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        return int.Parse(anEnum.ToString("d"));
    }
}

أي اقتراحات؟

هل كانت مفيدة؟

المحلول

إذا كنت لا تريد أن يلقي،

Convert.ToInt32()

يمكن أن تفعل الخدعة.

المصبوب المباشر (عبر (int)enumValue) غير ممكن. لاحظ أن هذا سيكون أيضا "خطيرا" منذ أن أصبح هناك أنواعا أساسية مختلفة (int, long, byte...).

أكثر رسميا: System.Enum لا يوجد لديه علاقة الميراث المباشرة مع Int32 (على الرغم من كلاهما ValueTypeق)، لذلك لا يمكن أن يكون المصبوب الصريح صحيحا داخل نظام النوع

نصائح أخرى

حصلت عليه للعمل عن طريق الصب إلى كائن ثم إلى INT:

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return (int)((object)enumValue);
    }
}

هذا قبيح وربما ليس أفضل طريقة. سأستمر في العبث معها، لمعرفة ما إذا كان بإمكاني التوصل إلى شيء أفضل ....

عدل

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

اختبار:

int x = DayOfWeek.Friday.ToInt();
Console.WriteLine(x); // results in 5 which is int value of Friday

تحرير 2: في التعليقات، قال أحدهم إن هذا يعمل فقط في C # 3.0. أنا فقط اختبرت هذا في VS2005 مثل هذا الأمر وعملت:

public static class Helpers
{
    public static int ToInt(Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

    static void Main(string[] args)
    {
        Console.WriteLine(Helpers.ToInt(DayOfWeek.Friday));
    }

إذا كنت بحاجة إلى تحويل أي ENUM إلى نوعها الأساسي (وليس كل العادة مدعومة من قبل int) ثم يمكنك استخدام:

return System.Convert.ChangeType(
    enumValue,
    Enum.GetUnderlyingType(enumValue.GetType()));

لماذا تحتاج إلى إعادة اختراع العجلة مع طريقة مساعد؟ انها قانونية تماما لتلقي enum القيمة لنوعها الأساسي.

انها أقل طباعة، وفي رأيي أكثر قراءة، لاستخدام ...

int x = (int)DayOfWeek.Tuesday;

... بدلا من شيء مثل ...

int y = Converter.ToInteger(DayOfWeek.Tuesday);
// or
int z = DayOfWeek.Tuesday.ToInteger();

من إجابتي هنا:

منح e كما هو الحال في:

Enum e = Question.Role;

ثم هذه العمل:

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);

آخر اثنين قبيح عادي. يجب أن يكون أول واحد أكثر قابلية للقراءة، على الرغم من أن الثانية أسرع بكثير. أو قد تكون طريقة تمديد هي الأفضل، أفضل ما في العالمين.

public static int GetIntValue(this Enum e)
{
    return e.GetValue<int>();
}

public static T GetValue<T>(this Enum e) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
    return (T)(object)e;
}

الآن يمكنك الاتصال:

e.GetValue<int>(); //or
e.GetIntValue();

صب من أ System.Enum إلى int يعمل بشكل جيد بالنسبة لي (انها أيضا على MSDN.). ربما يكون خطأ resharper.

نظرا لأن العادة تقتصر على البايت، SBYTE، SHORT، USHORT، INT، UINT، LONG و ULONG، يمكننا أن نجعل بعض الافتراضات.

يمكننا تجنب الاستثناءات أثناء التحويل باستخدام أكبر حاوية متوفرة. لسوء الحظ، أي حاوية لاستخدامها ليست واضحة لأن ULONG ستفجر للأرقام السالبة وستفجر طويلا للأرقام بين long.maxvalue و ulong.maxvalue. نحتاج إلى التبديل بين هذه الاختيارات بناء على النوع الأساسي.

بالطبع، لا تزال بحاجة إلى تحديد ما يجب القيام به عندما لا تناسب النتيجة داخل INT. أعتقد أن الصب على ما يرام، ولكن لا يزال هناك بعض gotchas:

  1. بالنسبة للعودة المستندة إلى نوع مع مساحة حقل أكبر من INT (الطويلة والأولونغ)، فمن الممكن أن بعض العادة ستقيم بنفس القيمة.
  2. إلقاء عدد أكبر من int.maxvalue سوف يرمي استثناء إذا كنت في منطقة فحص.

إليك اقتراحي، سأترك الأمر للقارئ لتحديد مكان اكتشاف هذه الوظيفة؛ كمساعد أو امتداد.

public int ToInt(Enum e)
{
  unchecked
  {
    if (e.GetTypeCode() == TypeCode.UInt64)
      return (int)Convert.ToUInt64(e);
    else
      return (int)Convert.ToInt64(e);
  }
}

لا تنس أن نوع ENUM نفسه يحتوي على مجموعة من وظائف المساعد الثابتة فيه. إذا كان كل ما تريد القيام به هو تحويل مثيل Enum إلى نوعها الصحيح المقابل، فإن الصب هو الطريقة الأكثر فعالية.

أعتقد أن RESHRAPER هو يشكو لأن العادة ليس تعدادا لأي نوع معين، والتعداد أنفسهم تستمد من فالتهايب العددية، وليس المعين. إذا كنت بحاجة إلى صب قابلة للتكيف بطريقة عامة، أود أن أقول أن هذا يمكن أن يناسبك جيدا (لاحظ أن نوع التعداد نفسه مدرج أيضا في Generic:

public static EnumHelpers
{
    public static T Convert<T, E>(E enumValue)
    {
        return (T)enumValue;
    }
}

يمكن بعد ذلك استخدام هذا مثل ذلك:

public enum StopLight: int
{
    Red = 1,
    Yellow = 2,
    Green = 3
}

// ...

int myStoplightColor = EnumHelpers.Convert<int, StopLight>(StopLight.Red);

لا أستطيع أن أقول مؤكد عن الجزء العلوي من رأسي، ولكن قد يتم دعم التعليمات البرمجية أعلاه من قبل استنتاج نوع C #، مما يسمح لما يلي:

int myStoplightColor = EnumHelpers.Convert<int>(StopLight.Red);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top