需要找到嵌套的 dto 对象的 属性
Need to find the nested dto object's property
我有以下带有虚拟数据的 DTO。我想从 StandardDTO 对象中找出条目列表的计数:-
public class StandardDTO
{
public string InternalNotes { get; set; }
public string CustomerNotes { get; set; }
public List<Principal> Principals { get; set; }
public VerificationSummary VerificationSummary{ get; set; }
}
public class Principal
{
public string PrincipalTitle { get; set; }
public string PrincipalName { get; set; }
}
public class VerificationSummary
{
public List<Entry> Entries { get; set; }
public decimal GrossTotal { get; set; }
public decimal Total { get; set; }
}
public class Entry
{
public string PeriodName { get; set; }
public decimal Amount { get; set; }
}
void Main()
{
// Need to populate stdDTOObject and childXElement
int count = GetDTOObjectCount(GetStandardDTOObject(), "VerificationSummary");
count.Dump();
}
public StandardDTO GetStandardDTOObject()
{
StandardDTO stdDTOObj = new StandardDTO();
stdDTOObj.InternalNotes = "InternalNotes";
stdDTOObj.CustomerNotes = "CustomerNotes";
List<Principal> lstPrincipal = new List<Principal>();
Principal pObj = new Principal();
pObj.PrincipalTitle = "Mr";
pObj.PrincipalName = "ABC";
lstPrincipal.Add(pObj);
pObj = new Principal();
pObj.PrincipalTitle = "Mrs";
pObj.PrincipalName = "XYZ";
lstPrincipal.Add(pObj);
stdDTOObj.Principals = lstPrincipal;
VerificationSummary vs = new VerificationSummary();
List<Entry> lstEntry = new List<Entry>();
Entry entry = new Entry();
entry.PeriodName = "Sept17";
entry.Amount = 1212;
lstEntry.Add(entry);
entry = new Entry();
entry.PeriodName = "Oct17";
entry.Amount = 12000;
lstEntry.Add(entry);
entry = new Entry();
entry.PeriodName = "Nov17";
entry.Amount = 1000;
lstEntry.Add(entry);
entry = new Entry();
entry.PeriodName = "Dec17";
entry.Amount = 2000;
lstEntry.Add(entry);
entry = new Entry();
entry.PeriodName = "Jan18";
entry.Amount = 2000;
lstEntry.Add(entry);
vs.Entries = lstEntry;
vs.GrossTotal = 5555;
vs.Total = 10000;
stdDTOObj.VerificationSummary = vs;
return stdDTOObj;
}
public int GetDTOObjectCount<T>(T dtoObject, string nodeName)
{
var dtoObjectType = dtoObject.GetType();
var objectProperties = GetPropertyInfo(dtoObjectType);
return GetDTOOBjectCountRecursively(objectProperties, nodeName, dtoObject);
}
public int GetDTOOBjectCountRecursively<T>(IEnumerable<PropertyInfo> objectProperties, string nodeName, T dtoObject)
{
foreach (PropertyInfo propInfo in objectProperties)
{
if (propInfo.Name.Equals(nodeName, StringComparison.OrdinalIgnoreCase))
{
var lstDTOItems = propInfo.GetValue(dtoObject) as IList;
if (lstDTOItems != null)
{
return lstDTOItems.Count;
}
else
{
var objPropInfos = GetPropertyInfo(propInfo.PropertyType);
//hardcoded the nodeName just for this test.
return GetDTOOBjectCountRecursively(objPropInfos, "Entries", dtoObject);
}
}
}
return 0;
}
private IEnumerable<PropertyInfo> GetPropertyInfo(Type type)
{
return type.GetProperties();
}
问题是我无法在内部递归循环
StandardDTO -> VerificationSummary -> 条目
当 propinfo = "Entries" propinfo
时在下一行失败
var lstDTOItems = propInfo.GetValue(dtoObject) as IList;
好的。
所以错误是由于以下语句而发生的:
return GetDTOOBjectCountRecursively(objPropInfos, "Entries", dtoObject);
发送"Entries"时,您需要发送已进展到的新对象,如下所示:
return GetDTOOBjectCountRecursively(objPropInfos, "Entries", propInfo.GetValue(dtoObject));
这应该可以解决问题。
此外,要检查通用列表,而不是这样做:
var lstDTOItems = propInfo.GetValue(dtoObject) as IList;
你可以使用这个方法:
private bool IsList(Object obj)
{
return obj is IList && obj.GetType().IsGenericType;
}
哪个会更健壮。
为什么要用反射?
你可以简单地写:
var obj = GetStandardDTOObject();
var count = obj.VerificationSummary.Entries.Count();
我有以下带有虚拟数据的 DTO。我想从 StandardDTO 对象中找出条目列表的计数:-
public class StandardDTO
{
public string InternalNotes { get; set; }
public string CustomerNotes { get; set; }
public List<Principal> Principals { get; set; }
public VerificationSummary VerificationSummary{ get; set; }
}
public class Principal
{
public string PrincipalTitle { get; set; }
public string PrincipalName { get; set; }
}
public class VerificationSummary
{
public List<Entry> Entries { get; set; }
public decimal GrossTotal { get; set; }
public decimal Total { get; set; }
}
public class Entry
{
public string PeriodName { get; set; }
public decimal Amount { get; set; }
}
void Main()
{
// Need to populate stdDTOObject and childXElement
int count = GetDTOObjectCount(GetStandardDTOObject(), "VerificationSummary");
count.Dump();
}
public StandardDTO GetStandardDTOObject()
{
StandardDTO stdDTOObj = new StandardDTO();
stdDTOObj.InternalNotes = "InternalNotes";
stdDTOObj.CustomerNotes = "CustomerNotes";
List<Principal> lstPrincipal = new List<Principal>();
Principal pObj = new Principal();
pObj.PrincipalTitle = "Mr";
pObj.PrincipalName = "ABC";
lstPrincipal.Add(pObj);
pObj = new Principal();
pObj.PrincipalTitle = "Mrs";
pObj.PrincipalName = "XYZ";
lstPrincipal.Add(pObj);
stdDTOObj.Principals = lstPrincipal;
VerificationSummary vs = new VerificationSummary();
List<Entry> lstEntry = new List<Entry>();
Entry entry = new Entry();
entry.PeriodName = "Sept17";
entry.Amount = 1212;
lstEntry.Add(entry);
entry = new Entry();
entry.PeriodName = "Oct17";
entry.Amount = 12000;
lstEntry.Add(entry);
entry = new Entry();
entry.PeriodName = "Nov17";
entry.Amount = 1000;
lstEntry.Add(entry);
entry = new Entry();
entry.PeriodName = "Dec17";
entry.Amount = 2000;
lstEntry.Add(entry);
entry = new Entry();
entry.PeriodName = "Jan18";
entry.Amount = 2000;
lstEntry.Add(entry);
vs.Entries = lstEntry;
vs.GrossTotal = 5555;
vs.Total = 10000;
stdDTOObj.VerificationSummary = vs;
return stdDTOObj;
}
public int GetDTOObjectCount<T>(T dtoObject, string nodeName)
{
var dtoObjectType = dtoObject.GetType();
var objectProperties = GetPropertyInfo(dtoObjectType);
return GetDTOOBjectCountRecursively(objectProperties, nodeName, dtoObject);
}
public int GetDTOOBjectCountRecursively<T>(IEnumerable<PropertyInfo> objectProperties, string nodeName, T dtoObject)
{
foreach (PropertyInfo propInfo in objectProperties)
{
if (propInfo.Name.Equals(nodeName, StringComparison.OrdinalIgnoreCase))
{
var lstDTOItems = propInfo.GetValue(dtoObject) as IList;
if (lstDTOItems != null)
{
return lstDTOItems.Count;
}
else
{
var objPropInfos = GetPropertyInfo(propInfo.PropertyType);
//hardcoded the nodeName just for this test.
return GetDTOOBjectCountRecursively(objPropInfos, "Entries", dtoObject);
}
}
}
return 0;
}
private IEnumerable<PropertyInfo> GetPropertyInfo(Type type)
{
return type.GetProperties();
}
问题是我无法在内部递归循环 StandardDTO -> VerificationSummary -> 条目
当 propinfo = "Entries" propinfo
时在下一行失败var lstDTOItems = propInfo.GetValue(dtoObject) as IList;
好的。
所以错误是由于以下语句而发生的:
return GetDTOOBjectCountRecursively(objPropInfos, "Entries", dtoObject);
发送"Entries"时,您需要发送已进展到的新对象,如下所示:
return GetDTOOBjectCountRecursively(objPropInfos, "Entries", propInfo.GetValue(dtoObject));
这应该可以解决问题。
此外,要检查通用列表,而不是这样做:
var lstDTOItems = propInfo.GetValue(dtoObject) as IList;
你可以使用这个方法:
private bool IsList(Object obj)
{
return obj is IList && obj.GetType().IsGenericType;
}
哪个会更健壮。
为什么要用反射?
你可以简单地写:
var obj = GetStandardDTOObject();
var count = obj.VerificationSummary.Entries.Count();