繁体   English   中英

提取类型的列表属性 <T> 使用反射

[英]Extracting a list property of type <T> using Reflection

我有一个包含许多其他对象列表的对象。 我将提供一个简单的示例。

public class BaseApplicationData
{
    public long Id { get; set; }
}
public class Phone : BaseApplicationData
{
    public string PhoneType { get; set; }
    public string Number { get; set; }
    public string Extension { get; set; }
}
public class Employer : BaseApplicationData
{
    public double Salary { get; set; }
    public string Name { get; set; }
    public string EmployementType { get; set; }
}
public class Applicant : BaseApplicationData
{
    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public List<Phone> PhoneNumbers { get; set; }
    public List<Employer> Employers { get; set; }
}

在我正在使用的实际代码中,有很多这样的列表。 在处理过程中,我们需要能够对这些列表中的每一个执行CRUD操作。 每个列表的过程相同。 因此,我没有为每个列表类型编写一组CRUD方法,而是想到可以使用泛型和/或反射为每个列表完成这些操作。

因此,我创建了一个可以做到这一点的方法,但结果却出乎意料。 使用上面的示例对象,我创建了一个申请人对象,并向其添加了一个雇主对象。 (这是模拟其中已有数据的列表。)然后,我调用了我的方法(如下所示)。

public long CreatePropertyValue<T>(Applicant applicant, T data, string propertyName)
{
    long newId = 0;
    var listproperty = applicant.GetType().GetProperty(propertyName);
    // Here is the problem, even with data in the list, listData.Count is always 0.
    List<T> listData = listproperty.GetValue(applicant, null) as List<T>;
    // psuedo code
    if list is null, create a new list
    assign a new Id value to object data (parameter)
    Add the data item to the list
    update the property of the applicant object with the updated list
    return newId;
}

对该方法的调用看起来像这样。 test.CreatePropertyValue(申请人,emp,“雇主”);

当我在列表中没有数据的情况下调用此方法时,按预期值将为null。 当我已经用列表中的数据调用它时,listData的值是正确类型的列表,但列表中的项为零。 查看listproperty.PropertyType.GetGenericArguments()我可以看到列表中的实际项目。 我希望能够基于propertyName获取listData的集合并键入T,然后能够将T数据项添加到列表中并保存回去。 同样,我还需要能够更新,删除和返回列表。

我看过网站上的几个问题,但是没有一个问题向我解释为什么当我在属性上使用getvalue时为什么我的列表包含0个项目。

我会很感激您能提供的任何帮助。

谢谢

更新 :愚蠢的我,我在创建数组和对象,但没有将对象添加到数组中。 这里没什么好看的,离开。

也许,尝试使用lambda:

    public void Test1()
    {
        var app = new Applicant();

        CreatePropertyValue(app, new Phone(), a => a.PhoneNumbers, (a, v) => a.PhoneNumbers = v);
        CreatePropertyValue(app, new Employer(), a => a.Employers, (a, v) => a.Employers = v);
    }

    public static long CreatePropertyValue<T>(Applicant applicant, T data, Func<Applicant, List<T>> getter, Action<Applicant, List<T>> setter)
        where T : BaseApplicationData
    {
        long newId = 0;

        var list = getter(applicant); //get list
        if (list == null) //check it
        {
            list = new List<T>();
            data.Id = newId;
            list.Add(data); //add new data
            setter(applicant, list); //set new list
        }
        return newId;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM