如何在Silverlight中创建一个GetEnumValues扩展方法,其工作方式与.NET相同?

下面是一段我觉得有用的代码,我可以用它来快速压缩枚举。 CurrentEnum存储对用于提供字符串的枚举的引用,在本例中为“Bald”,它可以更改。

我想要做的是复制Silverlight中没有GetEnumValues函数的相同function。 优选的解决方案是扩展方法,可以使用与下面示例相同的方式。

class Program { enum Cats { Fluffy, Furry, Bald }; enum Dogs { Big, Fat, Ugly }; static Type CurrentEnum = typeof(Cats); static void Main(string[] args) { Int32 i = (Int32)Enum.Parse(CurrentEnum, "Bald", true); i = i == CurrentEnum.GetEnumValues().Length - 1 ? 0 : i + 1; String nextValue = CurrentEnum.GetEnumValues().GetValue(i).ToString(); Console.WriteLine(nextValue); Console.ReadKey(); } } 

更新:

这是我现在决定的:

 public static class Extensions { public static Array GetEnumValues(this Type enumType) { if (enumType == null) throw new ArgumentException("Type 'enumType' cannot be null"); if (!enumType.IsEnum) throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); Int32 i = 0; Boolean bDefined = true; List list = new List(); do { if (Enum.IsDefined(enumType, i)) { list.Add(Enum.GetName(enumType, i)); ++i; } else { bDefined = false; } } while (bDefined); return list.ToArray(); } } 

如果我不得不猜测(未经测试):

  public static Array GetValues(Type type) { var fields = type.GetFields(BindingFlags.Static | BindingFlags.Public); Array result = Array.CreateInstance(type, fields.Length); for(int i = 0 ; i < fields.Length ; i++) { result.SetValue(Enum.ToObject(type, fields[i].GetValue(null)), i); } return result; } 

请注意,我不打算在这里解决订购问题; 字段的顺序明确没有定义。 因此,使用它来获取没有特定顺序的值。

在通过Silverlight中的枚举迭代时还有另一个与此类似的问题? 但是没有一个答案提供了一个完全复制GetEnumValues() (和GetEnumNames() )工作方式的实现。 我使用了该问题的一个答案来创建一个解决方案,它可以满足您的需求; 我相信这完全复制了Silverlight中这些函数的.NETfunction,我已经上传了Silverlight的整个测试项目,我用它来创建函数并测试用法: GetEnumValuesSilverlightImpl-StackOverflow-7062208.zip 。

应用程序本身是一个带有单个按钮和文本区域的表单。 单击该按钮可迭代四个不同枚举的三个值中的每一个,并将这些值记录到表单中。 添加额外的测试用例应该很容易,但要注意文本区域不会自动换行,因此如果希望将值放在比文本区域更宽的位置,则需要考虑这些情况。 我测试了原始海报的测试用例,写出了两个原始枚举的所有三个值,为我创建的具有三个非连续值的枚举写出了所有三个值,并为我创建的[Flag]枚举写出了所有三个值有三个不同的旗帜值。

相关代码:

EnumValuesExtensions.cs :包含函数调用的扩展类

 using System; using System.Linq; using System.Reflection; namespace SilverlightApplication1 { public static class EnumValuesExtensions { public static Array GetEnumValues(this Type EnumType) { if (!EnumType.IsEnum) throw new ArgumentException("GetEnumValues: Type '" + EnumType.Name + "' is not an enum"); return ( from field in EnumType.GetFields(BindingFlags.Public | BindingFlags.Static) where field.IsLiteral select (object)field.GetValue(null) ) .ToArray(); } public static string[] GetEnumNames(this Type EnumType) { if (!EnumType.IsEnum) throw new ArgumentException("GetEnumNames: Type '" + EnumType.Name + "' is not an enum"); return ( from field in EnumType.GetFields(BindingFlags.Public | BindingFlags.Static) where field.IsLiteral select field.Name ) .ToArray(); } } } 

MainPage.xaml.cs :包含测试代码的表单源

 using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Reflection; namespace SilverlightApplication1 { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } [Flags] enum Insects { Creepy = 0x0001, Creepier = 0x0002, Creepiest = 0x0004 }; enum Cats { Fluffy, Furry, Bald }; enum Dogs { Big, Fat, Ugly }; enum Rodents { Cute = 3, Cuter = 7, Cutest = 32 }; static Type CurrentEnum = typeof(Cats); private void btnRunTests_Click(object sender, RoutedEventArgs e) { // from original test code Int32 i = (Int32)Enum.Parse(CurrentEnum, "Bald", true); i = i == CurrentEnum.GetEnumValues().Length - 1 ? 0 : i + 1; String nextValue = CurrentEnum.GetEnumValues().GetValue(i).ToString(); textBlock1.Text += nextValue + Environment.NewLine; // new test code LogEnum(typeof(Cats)); LogEnum(typeof(Dogs)); LogEnum(typeof(Rodents)); LogEnum(typeof(Insects)); } public void LogEnum(Type T) { Array CurrentEnumValues; CurrentEnumValues = T.GetEnumValues(); for (int i=0; i < CurrentEnumValues.Length; ++i) { string EnumName = CurrentEnumValues.GetValue(i).ToString(); int EnumValue = (int)CurrentEnumValues.GetValue(i); textBlock1.Text += "[" + EnumName + " = " + EnumValue.ToString() + "], "; } textBlock1.Text += Environment.NewLine; } } } 

MainPage.xaml :测试表单的XAML

       

这些测试在Silverlight 3中运行,并且GetEnumValues()扩展看起来与.NET GetEnumValues()函数的工作方式相同,因为它在调用.ToString()时给出枚举名称,并在转换为时提供正确的整数值( INT)。

我没有测试过GetEnumNames()扩展,但是相当明显地类似于GetEnumValues()扩展,但是如果有任何问题我会很高兴看看。

感谢ptoinson和Shimmy对类似问题 的回答 , 这个问题构成了我写回答这个问题的函数的基础。

这有两个线程,我无法得到任何工作。 在摸索了一天后,我终于得到了这样的结论:

  public static Array GetEnumValues(this Type enumType) { List enumerations = new List(); FieldInfo[] fields = enumType.GetFields(BindingFlags.Static | BindingFlags.Public); object enumObj = enumType.GetType(); foreach (FieldInfo fieldInfo in fields) { enumerations.Add((int)fieldInfo.GetValue(enumObj)); } return enumerations.ToArray(); }