我正在开发一个包含多个(11)网络服务电话的网络服务应用程序。
对于每个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;
...
}
而不是分别为每一个(在11个自定义服务类中的每一个中)执行此操作,我想知道有没有办法传入分部类 wsSoapBody (沿着使用字符串数组)并循环遍历类的所有成员,从字符串数组中分配值?
修改:
我搜索并找到SO: 531384/how-to-loop-through-all-the-properties-of-a-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 ...
那我该去哪里?
答案 0 :(得分:1)
我不知道我是否理解你的问题:
if (aMessage[(int)DCSSCustomerUpdate_V3.Branch].ToString().Length != 0)
{
wsSoapBody.Branch = aMessage[(int)DCSSCustomerUpdate_V3.Branch].ToString();
}
所以你有这个枚举DCSSCustomerUpdate_V3
哪些成员匹配wsSoapBody
类的属性名称,你不想像上面那样重复代码,但是使用循环,对吗? / p>
您可以简单地遍历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());
}
}
答案 1 :(得分:1)
试试
DCSSCustomerUpdate_V3 t = (DCSSCustomerUpdate_V3)Enum.Parse(typeof(DCSSCustomerUpdate_V3), property.Name);
string value = aMessage[(int)t].ToString();
您还可以使用方法Enum.TryParse
对于通用枚举类型或多或少如此
public static void DisplayAll<TEnum>(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));
}
}
答案 2 :(得分:0)
public static void DisplayAll<TEnum>(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<DCSSCustomerUpdate_V3>(wsSoapBody, aMessage);