【问题标题】:set properties of data class using reflection in constructor在构造函数中使用反射设置数据类的属性
【发布时间】:2015-11-14 10:51:57
【问题描述】:

我有几个以与下面类似的方式定义的数据类,我正在尝试决定是为每个数据类提供一个内置构造函数来填充成员,还是在调用方法中只使用一次反射:

public class reportData
{

public List<Deposits> Deposits;
}

public class Deposits
{
    public Deposits(List<Dictionary<string, string>> LPQReq)
    {
        PropertyInfo[] properties = typeof(Deposits).GetProperties();

        foreach (Dictionary<string, string> PQList in LPQReq)
        {
            foreach (KeyValuePair<string, string> kvp in PQList)
            {
                MemberInfo info = typeof(Deposits).GetField(kvp.Key) as MemberInfo ?? typeof(Deposits).GetProperty(kvp.Key) as MemberInfo;

                //PropertyInfo property = properties[kvp.Key];

                // info.setvalue
            }
        }
        foreach (PropertyInfo property in properties)
        {
            Console.WriteLine("Name: " + property.Name + ", Value: " + property.GetValue(typeof(Deposits), null));
        }
    }
    public string YPBRNO { get; set; }
    public string YPBNA { get; set; }
    public string YPTME { get; set; }
... cut for brevity

我想使用反射让我的构造函数获取字典键值对列表,并且键与属性名称匹配...

然后我可以使用类似的东西

PropertyInfo property = properties[kvp.Key];

info.setValue(typeof(Deposits), value, null);

当然,一种方法是遍历我的类型中的所有属性,并在调用setValue() 之前检查property.name=kvp.key 是否像这样:

        foreach (Dictionary<string, string> PQList in LPQReq)
        {
            foreach (KeyValuePair<string, string> kvp in PQList)
            {
                MemberInfo info = typeof(Deposits).GetField(kvp.Key) as MemberInfo ?? typeof(Deposits).GetProperty(kvp.Key) as MemberInfo;

                //PropertyInfo property = properties[kvp.Key];

                // info.setvalue
                foreach (PropertyInfo property in properties)
                {
                    if (property.Name==kvp.Key)
                    {
                        property.SetValue(typeof(Deposits), kvp.Value, null);
                    }
                    Console.WriteLine("Name: " + property.Name + ", Value: " + property.GetValue(typeof(Deposits), null));
                }
            }
        }

所以现在我已经做到了,这样做是不是一个好主意,在每个类的构造函数中(然后我必须在外部调用)

或者我应该在调用方法中使用反射来设置所有属性,而不必知道属性是什么......就像这样(这发生在一个循环中):

Type target = Type.GetType(DocumentType);
foreach (Dictionary<string, string> PQList in LPQReq)
{
    foreach (KeyValuePair<string, string> kvp in PQList)
    {
        PropertyInfo prop = target.GetProperty(kvp.Key);

        prop.SetValue (target, kvp.Value, null);
        }

        Console.WriteLine("Template Name = {0}", templateName);
        }

编辑:

只是想提一下,我确实阅读了SO 1044455: c-sharp-reflection-how-to-get-class-reference-from-string,以了解如何仅从名称返回数据类...

所以我最初以为我会在我的数据类之外使用反射,但遇到了一些障碍!

【问题讨论】:

  • 如果您不考虑性能,我只会继续这样做。
  • @Aron:是的,Reflection 相当慢,但这意味着我可以编写一种方法来填充十几个或更多数据类(这将是 VS 2013 报告的数据源)......和无论如何,对于这项服务,它可能是每小时 2 打交易的情况......所以在不到一秒的时间内测量的性能应该不会受到影响,因为目前我们正在使用 MS Word 打印报告,而且速度非常慢(至少 7 秒每个事务)由于 Word 互操作开销。

标签: c# reflection properties member


【解决方案1】:

SetValueGetValue 方法接受类的实例作为输入,而不是该类的 Type。当您想设置/获取您所在类的属性值时,您可以将this 传递给这些方法。

public Deposits(List<Dictionary<string, string>> LPQReq)
{
    PropertyInfo[] properties = typeof(Deposits).GetProperties();

    foreach (Dictionary<string, string> PQList in LPQReq)
    {
        foreach (KeyValuePair<string, string> kvp in PQList)
        {
            if(properties.Any(x=>x.Name == kvp.Key) && 
               properties[kvp.Key].PropertyType == typeof(string))
            {
                properties[kvp.Key].SetValue(this, kvp.Value);
                //                            ^ here we pass current instance
            }
        }
    }
    foreach (PropertyInfo property in properties)
    {
        Console.WriteLine("Name: " + property.Name + ", Value: " + 
                property.GetValue(this));
        //                         ^ here we pass current instance
    }
}

我从您的代码中不明白的是,为什么您有一个名称值字典列表?您只需要每个对象的键值字典。我猜你想启动同一个类的多个实例,如果是这样,你必须遍历列表并通过循环启动带有字典的类。像这样的:

构造函数:

public Deposits(Dictionary<string, string> PQList)
{
    PropertyInfo[] properties = typeof(Deposits).GetProperties();
    foreach (KeyValuePair<string, string> kvp in PQList)
    {
         if(properties.Any(x=>x.Name == kvp.Key) && 
            properties[kvp.Key].PropertyType == typeof(string))
         {
             properties[kvp.Key].SetValue(this, kvp.Value);
         }
    }
    foreach (PropertyInfo property in properties)
    {
        Console.WriteLine("Name: " + property.Name + ", Value: " + 
                property.GetValue(this));
    }
}

其他地方:

List<Diposits> list = new List<Diposits>()
foreach (Dictionary<string, string> PQList in LPQReq)
{
   list.Add(new Diposits(PQList));
}

【讨论】:

  • @TRahgooy:谢谢,字典是一个键值对列表,其中包含数据类成员的名称,以及从我取下的制表符分隔的字符串中获取的相应值iSeries 消息队列..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
相关资源
最近更新 更多