通常填充不同的类成员

我正在开发一个带有几(11)个Web服务调用的Web服务应用程序。

对于每个Web服务,我需要从字符串数组中填充Soap Body,如下所示:

if (aMessage[(int)DCSSCustomerUpdate_V3.Branch].ToString().Length != 0) { wsSoapBody.Branch = aMessage[(int)DCSSCustomerUpdate_V3.Branch].ToString(); } 

aMessage[int]是字符串数组,[int]由枚举常量定义 – 在这种情况下,它定义如下:

 private enum DCSSCustomerUpdate_V3 { MsgType = 0, MsgVersion = 1, WSName = 2, ReplyTo = 3, SourceSystem = 4, ... } 

部分类中的属性名称与枚举常量匹配,所以我想我也会传入枚举常量?

部分类在wsdl中定义如下:

 public partial class DCSSCustomerUpdateType { private string instIdField; private string branchField; ... } 

我不知道是否有一种方法可以传递部分类wsSoapBody (以及字符串数组)并循环遍历类的所有成员,分配值,而不是分别为每一个执行此操作(在11个自定义服务类中)从字符串数组?

编辑

我搜索并找到了SO:531384 / how-to-loop-through-all-the-properties-of-class?

所以我尝试了这个:

  public static void DisplayAll(Object obj, string[] aMessage) { Type type = obj.GetType(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo property in properties) { string value = aMessage[property.Name].ToString(); System.Diagnostics.Debug.WriteLine("Name: " + property.Name + ", Value: " + property.GetValue(obj, null)); } } 

但是string value = aMessage[property.Name].ToString(); 将不会编译 – 因为它正在寻找从枚举常量返回的int …

那我从哪里去?

试试吧

 DCSSCustomerUpdate_V3 t = (DCSSCustomerUpdate_V3)Enum.Parse(typeof(DCSSCustomerUpdate_V3), property.Name); string value = aMessage[(int)t].ToString(); 

你也可以使用方法Enum.TryParse

对于通用的Enum类型或多或少如此

  public static void DisplayAll(Object obj, string[] aMessage) where TEnum : struct, IComparable, IFormattable, IConvertible { if (!typeof(TEnum).IsEnum) { throw new ArgumentException("T must be an enumerated type"); } Type type = obj.GetType(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo property in properties) { TEnum t = (TEnum)Enum.Parse(typeof(TEnum), property.Name); string value = aMessage[t.ToInt32(Thread.CurrentThread.CurrentCulture)].ToString(); System.Diagnostics.Debug.WriteLine("Name: " + property.Name + ", Value: " + property.GetValue(obj, null)); } } 

看到这篇文章创建通用方法将T限制为枚举

我不知道我是否理解你的问题:

 if (aMessage[(int)DCSSCustomerUpdate_V3.Branch].ToString().Length != 0) { wsSoapBody.Branch = aMessage[(int)DCSSCustomerUpdate_V3.Branch].ToString(); } 

所以你有这个枚举DCSSCustomerUpdate_V3哪些成员匹配wsSoapBody类的属性名称,你不想像上面那样重复代码,但是使用循环,对吗?

您可以简单地遍历DCSSCustomerUpdate_V3所有元素并设置属性的值,如:

 // type of the enum; pass in as parameter var enumType = typeof(DCSSCustomerUpdate_V3) // get the type of wsSoapBody var t = wsSoapBody.GetType(); // loop over all elements of DCSSCustomerUpdate_V3 foreach(var value in Enum.GetValues(enumType)) { if (aMessage[(int)value].ToString().Length != 0) { // set the value using SetValue t.GetProperty(value.ToString()).SetValue(wsSoapBody, aMessage[(int)value].ToString()); } } 

感谢Fabio和Sloth ,这是我们构建的最终代码:

 public static void DisplayAll(Object obj, string[] aMessage) where TEnum : struct, IComparable, IFormattable, IConvertible /* * see https://stackoverflow.com/questions/28168982/generically-populate-different-classes-members * */ { try { // get the type of wsSoapBody Type type = obj.GetType(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo property in properties) { try { if (Enum.IsDefined(typeof(TEnum), property.Name)) { TEnum t = (TEnum)Enum.Parse(typeof(TEnum), property.Name, true); System.Diagnostics.Debug.WriteLine("Name: " + property.Name + ", Value: " + property.GetValue(obj, null) + "Type: " + property.PropertyType); // property.GetValue(obj, null).ToString() != "" && if ( t.ToInt32(Thread.CurrentThread.CurrentCulture) < aMessage.GetUpperBound(0) && aMessage[t.ToInt32(Thread.CurrentThread.CurrentCulture)].ToString() != "") { switch (property.PropertyType.ToString()) { case "System.String": string value = aMessage[t.ToInt32(Thread.CurrentThread.CurrentCulture)].ToString(); property.SetValue(obj, value, null); break; case "System.Int32": int iValue = Convert.ToInt32(aMessage[t.ToInt32(Thread.CurrentThread.CurrentCulture)].ToString()); property.SetValue(obj, iValue, null); break; case "System.Int64": long lValue = Convert.ToInt64(aMessage[t.ToInt32(Thread.CurrentThread.CurrentCulture)].ToString()); property.SetValue(obj, lValue, null); break; case "System.DateTime": DateTime dtValue = DateTime.ParseExact(aMessage[t.ToInt32(Thread.CurrentThread.CurrentCulture)].ToString(), "ddMMyyyy", System.Globalization.CultureInfo.InvariantCulture); property.SetValue(obj, dtValue, null); break; default: System.Diagnostics.Debugger.Break(); break; } } else { logBuilder("Common.DisplayAll", "Info", "", property.Name + " is empty or outside range", "Index number: " + t.ToInt32(Thread.CurrentThread.CurrentCulture).ToString()); System.Diagnostics.Debug.WriteLine(property.Name + " is empty or outside range", "Index number: " + t.ToInt32(Thread.CurrentThread.CurrentCulture).ToString()); } } else { logBuilder("Common.DisplayAll", "Info", "", property.Name + " is not defined in Enum", ""); System.Diagnostics.Debug.WriteLine(property.Name + " is not defined in Enum"); } } catch (Exception ex) { logBuilder("Common.DisplayAll", "Error", "", ex.Message, ""); emailer.exceptionEmail(ex); System.Diagnostics.Debugger.Break(); } System.Diagnostics.Debug.WriteLine("Name: " + property.Name + ", Value: " + property.GetValue(obj, null)); } } catch (Exception ex) { logBuilder("Common.DisplayAll", "Error", "", ex.Message, ""); emailer.exceptionEmail(ex); System.Diagnostics.Debugger.Break(); //throw; } return; } 

并称之为,我们使用:

 Common.DisplayAll(wsSoapBody, aMessage);