我有以下课程:
用户
public partial class User
{
public long iduser { get; set; }
public string email { get; set; }
public string name { get; set; }
public System.DateTime birthdate { get; set; }
public string about { get; set; }
public bool active { get; set; }
public System.DateTime created_date { get; set; }
public System.DateTime last_update { get; set; }
public string password { get; set; }
public string image { get; set; }
public string username { get; set; }
public virtual ICollection<Interest> Interests { get; set; }
}
兴趣
public partial class Interest
{
public long idinterest { get; set; }
public string name { get; set; }
public bool active { get; set; }
public System.DateTime last_update { get; set; }
public System.DateTime created_date { get; set; }
public string css_class { get; set; }
public virtual ICollection<User> Users { get; set; }
}
WSReturnUserGetById
public class WSReturnUserGetById
{
public long iduser { get; set; }
public string email { get; set; }
public string name { get; set; }
public System.DateTime birthdate { get; set; }
public string about { get; set; }
public List<WSReturnInterestGetById> Interests { get; set; }
}
和WSReturnInterestBetById
public class WSReturnInterestGetById
{
public long idinterest { get; set; }
public string name { get; set; }
public string css_class { get; set; }
}
我使用以下代码填充WSReturnUserGetById和User上的数据:
public T PopulateObjects<T>(object obj) where T : class, new()
{
if (obj == null) return null;
T Obj = new T();
PropertyInfo[] properties = obj.GetType().GetProperties();
foreach (PropertyInfo p in properties)
{
PropertyInfo objPf = typeof(T).GetProperty(p.Name);
if (objPf != null)
{
if (p.PropertyType == objPf.PropertyType)
{
objPf.SetValue(Obj, p.GetValue(obj));
}
}
}
return Obj;
}
我还有一个功能可以填充对象列表
public List PopulateObjectList(IEnumerable objects)其中T:class,new() {
List<T> response = new List<T>();
foreach (U obj in objects)
{
T Obj = new T();
if (obj != null)
{
PropertyInfo[] properties = obj.GetType().GetProperties();
foreach (PropertyInfo p in properties)
{
PropertyInfo objPf = typeof(T).GetProperty(p.Name);
if (objPf != null)
{
if (p.PropertyType == objPf.PropertyType)
{
objPf.SetValue(Obj, p.GetValue(obj));
}
}
}
}
response.Add(Obj);
}
return response;
}
当我使用该代码时,它的作用除了属性&#34;兴趣&#34;在User和WSReturnUserGetById中,&#39; couse的类型不同。所以,我试图调整,并使用此功能使其工作:
public object populateCompleteObj<T, U>(U mainobj) where T : class, new()
{
if (mainobj.GetType().IsGenericType && mainobj is IEnumerable)
{
List<T> response = new List<T>();
foreach (object obj in (IEnumerable)mainobj)
{
T Obj = new T();
if (obj != null)
{
PropertyInfo[] properties = obj.GetType().GetProperties();
foreach (PropertyInfo p in properties)
{
PropertyInfo objPf = typeof(T).GetProperty(p.Name);
if (objPf != null)
{
if (typeof(IEnumerable).IsAssignableFrom(objPf.PropertyType))
{
objPf.SetValue(Obj, populateCompleteObj<'objpf property class', 'obj property class'>(p.GetValue(obj)));
}
else if (p.PropertyType == objPf.PropertyType)
{
objPf.SetValue(Obj, p.GetValue(obj));
}
}
}
}
}
}
else
{
if (mainobj == null) return null;
T Obj = new T();
PropertyInfo[] properties = mainobj.GetType().GetProperties();
foreach (PropertyInfo p in properties)
{
PropertyInfo objPf = typeof(T).GetProperty(p.Name);
if (objPf != null)
{
if (p.PropertyType == objPf.PropertyType)
{
objPf.SetValue(Obj, p.GetValue(mainobj));
}
}
}
return Obj;
}
}
问题是我不知道如何获取属性信息的类,所以可以进行递归。有谁知道怎么做?
答案 0 :(得分:1)
根据我的理解,您希望以递归方式调用populateCompletedObj<T,U>
。这可以轻松完成,但我会先建议一些更改。
U
,我会从通用定义中删除它,而只是使用object
。populateCompletedObj
包裹在自己的对象中(如果尚未包含)让方法以递归方式调用,然后看起来像这样:
// this.GetType is the class that contains the method to call
var recurseMethod = this.GetType().GetMethod("populateCompletedObj").MakeGenericMethod(objPf.PropertyType);
然后您可以这样调用此方法:
// Invoke the method on the current instance with the property
recurseMethod.Invoke(this, new object[1] {p.GetValue(obj) });
毕竟我最终得到了这个:
public TDest ReflectionCopy<TDest>(object srcVal)
where TDest : class, new()
{
if (srcVal == null) { return null; }
TDest dest = new TDest();
var props = srcVal.GetType().GetProperties();
foreach (PropertyInfo p in props)
{
PropertyInfo objPf = typeof(TDest).GetProperty(p.Name);
if (objPf != null)
{
if (objPf.PropertyType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(objPf.PropertyType))
{
var destCollType = objPf.PropertyType.GenericTypeArguments[0];
var recurse = this.GetType().GetMethod("ReflectionCopy").MakeGenericMethod(destCollType);
IEnumerable srcList = (IEnumerable)p.GetValue(srcVal);
IList destlst = (IList)Activator.CreateInstance(objPf.PropertyType);
foreach(var srcListVal in srcList)
{
var destLstVal = recurse.Invoke(this, new object[1] { srcListVal });
destlst.Add(destLstVal);
}
objPf.SetValue(dest, destlst);
continue;
}
if (p.PropertyType == objPf.PropertyType)
{
objPf.SetValue(dest, p.GetValue(srcVal));
}
}
}
return dest;
}
总而言之,你可以从一种类型序列化,并使用类似JSON.net的方式反序列化到另一种类型,并避免所有这些痛苦。
public TDest SerializeCopy<TDest>(object srcVal)
where TDest : class, new()
{
if (srcVal == null) { return null; }
var temp = JsonConvert.SerializeObject(srcVal);
return JsonConvert.DeserializeObject<TDest>(temp);
}
以下是所有代码的要点:
答案 1 :(得分:0)
如果我理解你的意思,那么你正在寻找一种获得通用内在类型的方法。
string
中的List<string>
。
您可以使用以下代码实现此目的:
PropertyInfo objPf = typeof(T).GetProperty(p.Name);
var type = pi.PropertyType.GetGenericArguments()[0];