0

我有以下课程:

用户

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 与用户的数据:

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) where 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;
}

当我使用该代码时,除了 User 和 WSReturnUserGetById 中的属性“Interests”之外,它都可以工作,因为类型不同。所以,我正在尝试调整,并使用此功能使其工作:

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;
    }

}

问题是我不知道如何获取属性信息的类,所以可以进行递归。有谁知道该怎么做?

4

2 回答 2

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);
}

以下是所有代码的要点:

https://gist.github.com/garystanford/36932d38a785272ee907

于 2014-08-02T22:49:47.897 回答
0

如果我理解你的意思,你正在寻找一种方法来获得泛型的内部类型。

那是stringList<string>.

您可以使用以下代码实现此目的:

PropertyInfo objPf = typeof(T).GetProperty(p.Name);
var type = pi.PropertyType.GetGenericArguments()[0];
于 2014-08-02T18:29:01.980 回答