2013-08-08 5 views
9

कोड की मात्रा के लिए क्षमा करें, लेकिन इसे इस तरह से समझाना आसान है।जेनिक्स, enums और कस्टम विशेषताओं - क्या यह संभव है?

मैं एक कस्टम है विशेषता CustomUserData इस प्रकार के रूप में लागू:

public class CustomUserData : Attribute 
{ 
    public CustomUserData(object aUserData) 
    { 
     UserData = aUserData; 
    } 
    public object UserData { get; set; } 
} 

और के रूप में enums के लिए एक विस्तार विधि:

public static class EnumExtensions 
{ 
    public static TAttribute GetAttribute<TAttribute>(this Enum aValue) where TAttribute : Attribute 
    { 
     Type type = aValue.GetType(); 
     string name = Enum.GetName(type, aValue); 
     return type.GetField(name) 
        .GetCustomAttributes(false) 
        .OfType<TAttribute>() 
        .SingleOrDefault(); 
    } 

    public static object GetCustomUserData(this Enum aValue) 
    { 
     CustomUserData userValue = GetAttribute<CustomUserData>(aValue); 
     return userValue != null ? userValue.UserData : null; 
    } 
} 

मैं तो एक सहायक वर्ग जो serializes है/एक enum है कि deserializes इसके साथ जुड़े कस्टम डेटा निम्नानुसार हैं:

public static class ParameterDisplayModeEnumListHelper 
{ 
    public static List<ParameterDisplayModeEnum> FromDatabase(string aDisplayModeString) 
    { 
     //Default behaviour 
     List<ParameterDisplayModeEnum> result = new List<ParameterDisplayModeEnum>(); 

     //Split the string list into a list of strings 
     List<string> listOfDisplayModes = new List<string>(aDisplayModeString.Split(',')); 

     //Iterate the enum looking for matches in the list 
     foreach (ParameterDisplayModeEnum displayModeEnum in Enum.GetValues(typeof (ParameterDisplayModeEnum))) 
     { 
      if (listOfDisplayModes.FindIndex(item => item == (string)displayModeEnum.GetCustomUserData()) >= 0) 
      { 
       result.Add(displayModeEnum); 
      } 
     } 

     return result; 
    } 

    public static string ToDatabase(List<ParameterDisplayModeEnum> aDisplayModeList) 
    { 
     string result = string.Empty; 

     foreach (ParameterDisplayModeEnum listItem in aDisplayModeList) 
     { 
      if (result != string.Empty) 
       result += ","; 
      result += listItem.GetCustomUserData(); 
     } 

     return result; 
    } 
} 

हालांकि थाई रों विशिष्टको ParameterDisplayModeEnum है और मैं enums कि मैं क्रमबद्धता/अक्रमांकन के लिए इस तरह के इलाज के लिए की जरूरत का एक समूह है तो मैं के रूप में एक सामान्य ऐसे किया जाना पसंद करेंगे:

public static class EnumListHelper<TEnum> 
{ 
    public static List<TEnum> FromDatabase(string aDisplayModeString) 
    { 
     //Default behaviour 
     List<TEnum> result = new List<TEnum>(); 

     //Split the string list into a list of strings 
     List<string> listOfDisplayModes = new List<string>(aDisplayModeString.Split(',')); 

     //Iterate the enum looking for matches in the list 
     foreach (TEnum displayModeEnum in Enum.GetValues(typeof (TEnum))) 
     { 
      if (listOfDisplayModes.FindIndex(item => item == (string)displayModeEnum.GetCustomUserData()) >= 0) 
      { 
       result.Add(displayModeEnum); 
      } 
     } 

     return result; 
    } 

    public static string ToDatabase(List<TEnum> aDisplayModeList) 
    { 
     string result = string.Empty; 

     foreach (TEnum listItem in aDisplayModeList) 
     { 
      if (result != string.Empty) 
       result += ","; 
      result += listItem.GetCustomUserData(); 
     } 

     return result; 
    } 
} 

हालांकि इस काम नहीं करेगा चूंकि GetCustomUserData() को नहीं बुलाया जा सकता है। कोई सुझाव? मैं कस्टम विशेषता या enums के उपयोग का उपयोग नहीं कर सकता। मैं प्रत्येक बार एक ठोस सूची सहायक वर्ग लिखने के बिना serialization/deserialization करने के लिए एक सामान्य तरीका की तलाश में हूँ।

सभी सुझावों की सराहना की।

उत्तर

2

कोशिश इस कोड:

public static class EnumListHelper 
{ 
    private static void EnsureIsEnum<TEnum>() 
    { 
     if (!typeof(TEnum).IsEnum) 
      throw new InvalidOperationException(string.Format("The {0} type is not an enum.", typeof(TEnum))); 
    } 

    public static List<TEnum> FromDatabase<TEnum>(string aDisplayModeString) 
     where TEnum : struct 
    { 
     EnsureIsEnum<TEnum>(); 
     //Default behaviour 
     List<TEnum> result = new List<TEnum>(); 

     //Split the string list into a list of strings 
     List<string> listOfDisplayModes = new List<string>(aDisplayModeString.Split(',')); 

     //Iterate the enum looking for matches in the list 
     foreach (Enum displayModeEnum in Enum.GetValues(typeof(TEnum))) 
     { 
      if (listOfDisplayModes.FindIndex(item => item == (string)displayModeEnum.GetCustomUserData()) >= 0) 
      { 
       result.Add((TEnum)(object)displayModeEnum); 
      } 
     } 

     return result; 
    } 

    public static string ToDatabase<TEnum>(List<TEnum> aDisplayModeList) 
     where TEnum : struct 
    { 
     EnsureIsEnum<TEnum>(); 
     string result = string.Empty; 

     foreach (var listItem in aDisplayModeList.OfType<Enum>()) 
     { 
      if (result != string.Empty) 
       result += ","; 
      result += listItem.GetCustomUserData(); 
     } 

     return result; 
    } 
} 

var fromDatabase = EnumListHelper.FromDatabase<TestEnum>("test"); 
EnumListHelper.ToDatabase(fromDatabase); 

अद्यतन 0

स्पष्ट है, क्योंकि हम करने के लिए जेनरिक सीमित नहीं कर सकते Enum हमें जांचना चाहिए कि TEnum प्रकार एक enum है और अगर यह नहीं है तो एक अपवाद फेंकना चाहिए। जब हम FromDatabase विधि का उपयोग हम जानते हैं कि TEnum enum है, और हम निर्दिष्ट TEnum के लिए एक enum कास्ट करने के लिए इस कोड को लिख सकते हैं: ToDatabase विधि में

result.Add((TEnum)(object)displayModeEnum) 

हम भी जानते हैं कि TEnum enum है और हम कर सकते हैं Enum प्रकार के TEnum कन्वर्ट करने के लिए इस कोड को लिखें:

aDisplayModeList.OfType<Enum>() 
+0

कि महान है और बस चाहता हूँ मैं प्राप्त करने के लिए कोशिश कर रहा था। धन्यवाद। – TheEdge

+0

कृपया कोड न केवल डंप करें, समझाएं कि आपने क्या किया है। – CodeCaster

+1

@CodeCaster मैंने जवाब अपडेट किया। –

2

आदर्श रूप में आप Enum को TEnum प्रतिबंधित करना चाहते हैं लेकिन यह है कि जैसा कि आप Enum Microsoft
को जेनरिक सीमित नहीं कर सकते लेकिन निम्न प्रयास करें, यह चाल हो सकती काम नहीं करेगा हूँ ...

if (listOfDisplayModes.FindIndex(item => 
    item == (string)(displayModeEnum as Enum).GetCustomUserData()) >= 0) 
संबंधित मुद्दे