[英]Add to a collection of unknown type using reflection in c#
因此,我正在使用反射來遍歷一個對象的屬性,並使用相同名稱的屬性填充另一個對象上的值。 這很好用,但是當屬性類型是一個集合時,問題就來了。 我希望能夠遍歷源集合中的每個對象,並用源集合中的對象填充相同的列表。
public class SourceMessage
{
public string Name { get; set; }
public int Version { get; set; }
public IList<ValueDefinition> Values { get; set; }
}
public class ValueDefinition
{
public string Name { get; set; }
public string Value { get; set; }
}
public class TargetObject
{
public TargetObject()
{
Values = new List<TargetValueDefinition>();
}
public string Name { get; set; }
public int Version { get; set; }
public IList<TargetValueDefinition> Values { get; set; }
}
public class TargetValueDefinition
{
public string Name { get; set; }
public string Value { get; set; }
}
然后,我使用反射從源中填充目標。
public static void PopulateFromMessage<T, TS>(ref T targetEntity, TS message)
{
var sourceType = typeof(TS);
var targetType = typeof(T);
foreach (var targetPropInfo in targetType.GetProperties())
{
if (sourceType.GetProperty(targetPropInfo.Name) != null)
{
var obj = sourceType.GetProperty(targetPropInfo.Name);
if (obj.PropertyType.Namespace == "System.Collections.Generic")
{
//var x = targetType.GetProperty(targetPropInfo.Name);
//PopulateFromMessage(ref x, sourceType.GetProperty(targetPropInfo.Name));
continue;
}
targetPropInfo.SetValue(targetEntity, sourceType.GetProperty(targetPropInfo.Name).GetValue(message), null);
}
}
}
因此,調用此方法將是這樣的:
private void DenormalizeMessage(SourceMessage message)
{
var newTargetObject = new TargetObject();
PopulateFromMessage(ref newTargetObject , message);
}
我可以確定該屬性何時是一個集合,但不確定如何創建新的TargetValueDefinitions以及如何使用ValueDefinitions中的值填充它們。 最后,它幾乎是TargetObject形式的SourceMessage的副本。
這一切都源於接收消息並將它們轉換為具有相同屬性名稱的對象。
您應該為每個類創建一個接口(在接口上實現方法和屬性),並在每個類中實現它。 之后,在函數PopulateFromMessage中應指定方法所允許的接口,這樣您就可以直接使用具有T和TS泛型類型的類的屬性。
免責聲明:這樣做是非常不安全的,並且會做出很多假設,但它應該使您走上正確的道路。
將您的方法更改為此:
public static void PopulateFromMessage<T, TS>(T targetEntity, TS message)
{
var sourceType = typeof (TS);
var targetType = typeof (T);
foreach (var targetPropInfo in targetType.GetProperties())
{
if (targetPropInfo.PropertyType.IsGenericType)
{
if (targetPropInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>))
{
var originalList = sourceType.GetProperty(targetPropInfo.Name).GetValue(message) as IList;
if (originalList != null)
{
var argumentType = targetPropInfo.PropertyType.GetGenericArguments();
var listType = typeof (List<>);
var concreteType = listType.MakeGenericType(argumentType);
var newList = Activator.CreateInstance(concreteType) as IList;
foreach (var original in originalList)
{
var targetValue = Activator.CreateInstance(argumentType[0]);
// do this yourself. Here we're converting ValueDefinition to TargetValueDefinition
// targetValue.Fill(original);
}
targetPropInfo.SetValue(targetEntity, newList);
}
}
}
else
{
if (sourceType.GetProperty(targetPropInfo.Name) != null)
{
var obj = sourceType.GetProperty(targetPropInfo.Name);
if (obj.PropertyType.Namespace == "System.Collections.Generic")
{
//var x = targetType.GetProperty(targetPropInfo.Name);
//PopulateFromMessage(ref x, sourceType.GetProperty(targetPropInfo.Name));
continue;
}
targetPropInfo.SetValue(targetEntity, sourceType.GetProperty(targetPropInfo.Name).GetValue(message), null);
}
}
}
}
如果您的問題是遍歷單個屬性(當它是一個集合時)中包含的項目,那么關鍵是將屬性值讀入動態變量而不是默認情況下的對象變量,這樣您就可以將foreach用於它。
dynamic propVal = inputProperty.GetValue(item);
foreach (var subItem in propVal)
{
//do your stuff
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.