【问题标题】:Get Properties of container class using .net reflection使用 .net 反射获取容器类的属性
【发布时间】:2015-01-25 08:08:04
【问题描述】:

我有一个类包含一组属性,其中一个属性是类类型 如下:

public class ProgramData
{
    public string code { get; set; }
    public string message { get; set; }

    public string program_id { get; set; }
    public string email { get; set; }
    public string first_name { get; set; }
    public string last_name { get; set; }

    public GeneralSetup general_setup { get; set; }
}

public class GeneralSetup
{
    public string store_name { get; set; }

    public bool store_enabled { get; set; }

    public bool promotions_enabled { get; set; }

    public bool barcode_scan_enabled { get; set; }

    public bool barcode_generate_enabled { get; set; }

}

我有一个通用方法 [因为我有一组类] 来验证属性,我使用反射来动态获取道具名称和值并且它工作正常,但问题是当它验证 general_setup 属性时它会获取它的道具和开始验证它们。 根据我的业务规则,如果它是 string.empty,我想设置容器类的 [code and message] 道具,我无法在这个级别获得这个道具。 有任何想法吗?谢谢

public T ValidateObjectFields<T>(T entity) where T : class
    {
        Type objType = entity.GetType();
        PropertyInfo[] properties = objType.GetProperties();
        foreach (PropertyInfo property in properties)
        {
            object propValue = property.GetValue(entity, null);
            var elems = propValue as IList;
            if (elems != null)
            {
                foreach (var item in elems)
                    ValidateObjectFields(item);
            }
            else
            {
                // Check if current property has sub object
                if (property.PropertyType.Assembly == objType.Assembly)
                {
                    #region Validate Objects

                        var code = objType.GetProperty("code");
                        var mesg = objType.GetProperty("message");


                        // in this case the property has sub object and i want to get these properties of container class
                        if (code == null && mesg == null) 
                        {
                            code = objType.GetProperty("code", BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public);
                            mesg = objType.GetProperty("message", BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public);
                        }

                        if (String.IsNullOrEmpty(Convert.ToString(propValue)))
                        {
                            //strDict = systemResponse.GetSystemResponse(Constants.structSystemResponses.Required_Field, //Constants.ConfigurableLanguages.English, Constants.enResponseSourceSystems.Webservice);
                            foreach (DictionaryEntry value in strDict)
                            {
                                code.SetValue(entity, Convert.ToString(value.Key), null);
                                mesg.SetValue(entity, Convert.ToString(value.Value) + " " + property.Name, null);
                            }
                            break;
                        }


                    #endregion

                    ValidateObjectFields(propValue);
                }
                else
                {
                    #region Validate Objects

                        var code = objType.GetProperty("code");
                        var mesg = objType.GetProperty("message");
                        // in this case the property has sub object and i want to get these properties of container class
                        if(code == null && mesg == null)
                        {
                            PropertyInfo[] info = objType.BaseType.GetProperties(BindingFlags.Public);

                            code = objType.GetProperty("code", BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public);
                            mesg = objType.GetProperty("message", BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public);
                        }

                        if (String.IsNullOrEmpty(Convert.ToString(propValue)))
                        {
                            strDict = systemResponse.GetSystemResponse(Constants.structSystemResponses.Required_Field, Constants.ConfigurableLanguages.English, Constants.enResponseSourceSystems.Webservice);
                            foreach (DictionaryEntry value in strDict)
                            {
                                code.SetValue(entity, Convert.ToString(value.Key), null);
                                mesg.SetValue(entity, Convert.ToString(value.Value) + " " + property.Name, null);
                            }
                            break;
                        }

                    #endregion
                }
            }
        }

        return entity;
    }

【问题讨论】:

  • 您能否指定您遇到问题的属性?以及在方法中您无法准确弄清楚的部分在哪里。
  • 我需要的属性“代码和消息”。当属性类型为对象时,我需要设置它们的值,因为它是一种递归方法。但是如果我将这两个属性放在一个类中并让其他类可以继承它可能会正常工作吗?
  • 您应该只在有意义的情况下使用继承,而不是作为您所面临问题的解决方法。

标签: c# reflection


【解决方案1】:

您可以为带有父元素的 ValidateObjectFields 编写重载,这样您就可以访问包含类的属性。

public TEntity ValidateObjectFields<TEntity>(TEntity entity, object Entity)
{
   //Here put the code for handling the properties.
}

在你上面的代码中调用这个方法

foreach (var item in elems)
    ValidateObjectFields(item,entity);

我认为这将解决您的问题。

【讨论】:

  • 非常感谢就像魅力一样。抱歉,我无法为您的答案投票,因为我没有足够的声誉。 @Manar
  • 将答案标记为正确。我想你可以。 @OmarAlmeani
猜你喜欢
  • 2018-06-05
  • 2014-03-08
  • 1970-01-01
  • 2017-06-10
  • 2017-05-14
  • 1970-01-01
  • 2014-04-13
  • 2012-01-23
  • 2011-06-28
相关资源
最近更新 更多