c# - जेनेरिक कक्षा में नेस्टेड एनम से प्रतिबिंब के माध्यम से enum मूल्य प्राप्त करें




generics reflection (2)

एक प्रकार का निर्माण एक कामकाज होगा लेकिन मेरे लिए अस्वीकार्य होगा, क्योंकि यह बहुत जटिल हो जाएगा।

मूल्यों को प्राप्त करने का यह एकमात्र तरीका है जो सामान्य रूप से व्यवहार करेगा।

आप खुले प्रकार के खेतों में जा सकते हैं, और विचित्र बात यह है कि आप इस तरह के मूल्यों को मूल्यों के लिए प्राप्त कर सकते हैं। आपको उन मानों का उपयोग करने से बचने की कोशिश करनी चाहिए, लेकिन आप उन्हें अपने अंतर्निहित प्रकार में परिवर्तित कर सकते हैं।

public static void Main()
{
   var enumType = typeof(Foo<>.Bar);
   var underlyingType = Enum.GetUnderlyingType(enumType);

   foreach(var field in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))
   {
       var value = field.GetValue(null);
       var underlyingValue = Convert.ChangeType(value, underlyingType);
       Console.WriteLine($"{field.Name} = {underlyingValue}");
   }
}

हालांकि, क्षेत्र का उपयोग करने के लिए एक बेहतर समाधान है। field.GetRawConstantValue() :

public static void Main()
{
   var enumType = typeof(Foo<>.Bar);

   foreach(var field in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))
   {
       Console.WriteLine($"{field.Name} = {field.GetRawConstantValue()}");
   }
}

इस तरह यदि सीएलआर कभी भी ऐसे अजीब मूल्यों को कभी भी उत्पादित करने से रोकने के लिए तय किया जाता है, तो आपका कोड नहीं टूट जाएगा।

मुझे प्रतिबिंब के माध्यम से प्राप्त कुछ प्रकारों से enum मानों और उनके संबंधित अंडरलिंग मूल्यों को मुद्रित करने की आवश्यकता है। यह ज्यादातर समय ठीक काम करता है। हालांकि अगर enum को सामान्य प्रकार के भीतर घोषित किया जाता है, तो Enum.GetValues निम्न अपवाद फेंकता है:

[System.NotSupportedException: Cannot create arrays of open type. ]  
at System.Array.InternalCreate(Void* elementType, Int32 rank, Int32* pLengths, Int32* pLowerBounds)    
at System.Array.CreateInstance(Type elementType, Int32 length)
at System.Array.UnsafeCreateInstance(Type elementType, Int32 length)   
at System.RuntimeType.GetEnumValues()

प्रजनन के लिए पूर्ण कोड:

using System;

public class Program
{
    public static void Main()
    {
       var enumType= typeof(Foo<>.Bar);
       var underlyingType = Enum.GetUnderlyingType(enumType);
       Console.WriteLine(enumType.IsEnum);

       foreach(var value in Enum.GetValues(enumType))
       {
           Console.WriteLine("{0} = {1}", value, Convert.ChangeType(value, underlyingType));
       }
    }

}

public class Foo<T>
{
    public enum Bar
    {
        A = 1,
        B = 2
    }
}

या इसे here परीक्षण here

क्या यह वांछित व्यवहार है और मैं आसपास कैसे काम करूं?

एक प्रकार का निर्माण एक वर्कअराउंड होगा लेकिन मेरे लिए अस्वीकार्य होगा, क्योंकि यह बहुत जटिल हो जाएगा।


फू जिसे एक खुला प्रकार कहा जाता है (एक प्रकार जो पूरी तरह परिभाषित नहीं है क्योंकि इसमें इसमें सामान्य है) और खुले प्रकार की सरणी की अनुमति नहीं है, आप इसे करके अनुकरण कर सकते हैं

Array.CreateInstance(typeof(Foo<>), 2)

और चूंकि एनम के GetValues ​​एक सरणी बनाने पर निर्भर है, यह विफल रहता है। आप इसके बजाय कर सकते हैं

var enumType = typeof(Foo<object>.Bar);

("ऑब्जेक्ट" एक डमी प्रकार है ताकि आप खुले प्रकार के साथ काम नहीं करेंगे) या जोन स्कीट ने सुझाव दिया है।





enums