2012-04-30 7 views
50

में जेनरिक एनम कास्ट इंट कास्ट Cast int to enum in C# के समान है लेकिन मेरा enum एक सामान्य प्रकार पैरामीटर है। सर्वोत्तम इसे संभालने का तरीका क्या है?सी #

उदाहरण:

private T ConvertEnum<T>(int i) where T : struct, IConvertible 
{ 
    return (T)i; 
} 

उत्पन्न संकलक त्रुटि Cannot convert type 'int' to 'T'

पूर्ण कोड, के रूप में इस प्रकार है जहां मूल्य पूर्णांक, या अशक्त समाहित कर सकता है।

private int? TryParseInt(string value) 
{ 
    var i = 0; 
    if (!int.TryParse(value, out i)) 
    { 
     return null; 
    } 
    return i; 
} 

private T? TryParseEnum<T>(string value) where T : struct, IConvertible 
{ 
    var i = TryParseInt(value); 
    if (!i.HasValue) 
    { 
     return null; 
    } 

    return (T)i.Value; 
} 
+0

http://stackoverflow.com/questions/2745320/enum-tryparse-with-flags-attribute - मदद कर सकता है ? – Sunny

+0

http://stackoverflow.com/questions/1331739/enum-type-constraints-in-c-sharp पर अंतिम उत्तर, जो आप चाहते हैं उसके करीब है। हालांकि यह अभी भी चालाक नहीं है। मैं इसके लिए प्रतिबिंब का उपयोग करता हूं, आप कोड को बहुत मजबूत बना सकते हैं। संरचना मेरी राय में जेनेरिक के साथ गड़बड़ी करने के लिए काफी प्रतिकूल नहीं है। –

+0

ऐसा कुछ जो बॉक्स नहीं करता है: [सी-तेज-गैर-मुक्केबाजी-रूपांतरण-जेनेरिक-एनम-टू-इंट] (http://stackoverflow.com/questions/1189144/c-sharp-non-boxing- रूपांतरण-का-जेनेरिक-एनम-टू-इंट) – nawfal

उत्तर

76

सबसे आसान तरीका मैं पाया है object करने के लिए एक डाली जोड़कर संकलक के हाथ मजबूर करने के लिए है।

return (T)(object)i.Value; 
+10

यदि आपको मुक्केबाजी पसंद नहीं है: [सी-तेज-गैर-मुक्केबाजी-रूपांतरण-जेनेरिक-एनम-टू-इंट] (http://stackoverflow.com/प्रश्न/1189144/सी-तेज-गैर-मुक्केबाजी-रूपांतरण-जेनेरिक-एनम-टू-इंट) – nawfal

+2

हम इंट के लिए enum कास्टिंग कर रहे हैं, इसके विपरीत आप इस सवाल के विपरीत नहीं हैं। इसके अलावा, उस प्रश्न का कोई समाधान नहीं है। – MatteoSp

+0

आप enum मानों के साथ एक स्थैतिक सरणी भी आवंटित कर सकते हैं, और उसके बाद सही enum पुनर्प्राप्त करने के लिए केवल अनुक्रमणिका में पास कर सकते हैं। यह किसी भी तरह का कास्टिंग करने के लिए बचाता है। उदाहरण (केवल इस पंक्ति के लिए लाइन 11,14, और 34 प्रासंगिक हैं): https://pastebin.com/iPEzttM4 – Krythic

11

आप इस के लिए Enum.Parse उपयोग करने के लिए सक्षम होना चाहिए: extenstion तरीकों के लिए सामान्य enums पार्स करने के बारे में

return (T)Enum.Parse(typeof(T), i.Value.ToString(), true); 

यह लेख वार्ता:

+0

@Guvante: मुझे लगता है कि मैंने मूल्य को मेरे उदाहरण में एक स्ट्रिंग में परिवर्तित कर दिया है। क्या आप इस मुद्दे को देखते हुए देखते हैं? –

14

यहाँ एक है तथ्य का दुरुपयोग करने वाला बहुत तेज़ समाधान कि रनटाइम स्थैतिक जेनेरिक वर्गों के कई उदाहरण बनाता है। अपने आंतरिक अनुकूलन राक्षसों को उजागर करें!

यह वास्तव में चमकता है जब आप एक सामान्य फैशन में एक स्ट्रीम से Enums पढ़ रहे हैं। एक बाहरी वर्ग के साथ मिलकर जो enum के अंतर्निहित प्रकार और बिटकॉन्टर को भयानक उजागर करने के लिए भी कैश करता है। अनुकूलन के साथ कोर i7-3740QM पर

void Main() 
{ 
    Console.WriteLine("Cast (reference): {0}", (TestEnum)5); 
    Console.WriteLine("EnumConverter: {0}", EnumConverter<TestEnum>.Convert(5)); 
    Console.WriteLine("Enum.ToObject: {0}", Enum.ToObject(typeof(TestEnum), 5)); 

    int iterations = 1000 * 1000 * 100; 
    Measure(iterations, "Cast (reference)",() => { var t = (TestEnum)5; }); 
    Measure(iterations, "EnumConverter",() => EnumConverter<TestEnum>.Convert(5)); 
    Measure(iterations, "Enum.ToObject",() => Enum.ToObject(typeof(TestEnum), 5)); 
} 

static class EnumConverter<TEnum> where TEnum : struct, IConvertible 
{ 
    public static readonly Func<long, TEnum> Convert = GenerateConverter(); 

    static Func<long, TEnum> GenerateConverter() 
    { 
     var parameter = Expression.Parameter(typeof(long)); 
     var dynamicMethod = Expression.Lambda<Func<long, TEnum>>(
      Expression.Convert(parameter, typeof(TEnum)), 
      parameter); 
     return dynamicMethod.Compile(); 
    } 
} 

enum TestEnum 
{ 
    Value = 5 
} 

static void Measure(int repetitions, string what, Action action) 
{ 
    action(); 

    var total = Stopwatch.StartNew(); 
    for (int i = 0; i < repetitions; i++) 
    { 
     action(); 
    } 
    Console.WriteLine("{0}: {1}", what, total.Elapsed); 
} 

परिणाम सक्षम:

Cast (reference): Value 
EnumConverter: Value 
Enum.ToObject: Value 
Cast (reference): 00:00:00.3175615 
EnumConverter: 00:00:00.4335949 
Enum.ToObject: 00:00:14.3396366 
+0

यह वास्तव में अच्छा है, धन्यवाद। हालांकि आप 'Expression.ConvertChecked' का उपयोग करना चाहेंगे, हालांकि, एनम प्रकार की श्रेणी के न्यूमेरिक ओवरफ़्लो के परिणामस्वरूप' ओवरफ्लो एक्सेप्शन 'होता है। –

0
public static class Extensions 
    { 
     public static T ToEnum<T>(this int param) 
     { 
      var info = typeof(T); 
      if (info.IsEnum) 
      { 
       T result = (T)Enum.Parse(typeof(T), param.ToString(), true); 
       return result; 
      } 

      return default(T); 
     } 
    } 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^