在构造函数中使用反射来设置数据类的属性 [英] set properties of data class using reflection in constructor

查看:78
本文介绍了在构造函数中使用反射来设置数据类的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几种数据类,其定义方式与以下类似,我正在尝试决定是否为每个数据类都具有内置的构造函数来填充成员,或者在调用方法中仅使用反射一次:

I have several data classes defined in a similar way to the below and am trying to decide whether to have a built-in constructor for each data class to populate the members, or use reflection only once in the calling method:

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

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

I would like to use reflection to have my constructor take a list of Dictionary key-value pairs, and the key matches the name of the property...

然后我可以使用

PropertyInfo property = properties[kvp.Key];

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

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

one way of course is to loop through all the properties in my type and check if the property.name=kvp.key before calling setValue() like so:

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

所以现在我已经到了这一步,以这种方式在每个类的构造函数中进行操作是一个好主意(然后我必须在外部进行调用)

so now I have got that far, is it a good idea to do it this way, inside the constructor of each class (that I must then invoke externally)

或者我应该在调用方法中使用反射来设置所有属性,而不必知道这些属性是什么……(这种情况发生在循环中):

or should I use the reflection in the calling method to set all the properties without having to know what the properties are...like this (this happens in a loop) :

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 找出如何仅从名称中返回数据类...

Just wanted to mention I did read SO 1044455: c-sharp-reflection-how-to-get-class-reference-from-string to find out how to return the data class just from a name ...

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

so I initially thought I would use the reflection outside of my data classes but came up against a few roadblocks!

推荐答案

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

SetValue and GetValue methods accept an instance of class as input not Type of that class. As you want to set/get values of the properties of the class you are in, you can pass this to these methods.

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

我对您的代码不了解的是,为什么要列出名称-值字典?您只需要每个对象的键值字典即可.我猜您想启动同一个类的多个实例,如果是这样,则必须遍历该列表,并通过该循环用字典启动该类.像这样:

What I'm not understanding from your code is, why you have a list of dictionary of name-values? you just need a dictionary of key-values for each object. I guess you want to initiate multiple instances of the same class, if so you must loop over the list and through the loop initiate the class with the dictionary. Something like this:

构造函数:

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

这篇关于在构造函数中使用反射来设置数据类的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆