【问题标题】:Get properties of property of a custom data type, with reflection c#使用反射c#获取自定义数据类型的属性的属性
【发布时间】:2014-09-15 19:55:31
【问题描述】:

简短说明: 我需要在将一些文本保存到数据库之前对其进行清理。 我们有一个项目,其中包含 MVC 应用程序中使用的所有模型。有一个Save(T record) 方法可以将实体保存到数据库中。我被要求做的是在将传入对象的字符串类型的每个属性保存到数据库之前对其进行清理。但是,有一个问题:如何从传入的实体中清理自定义数据类型的属性?

详细说明: 假设我有一个 Address 类型的类和一个 Person 类型的类,它具有 Address 类型的属性:

    public class Address
    {
        public string StreetName { get; set; }
        public string City { get; set; }
        public int StreetNumber { get; set; }
    }

    public class Person
    {
        public string PersonName { get; set; }
        public Address HomeAddress { get; set; }
    }

在我使用这个泛型方法来检索字符串类型的属性之前:

        public static void SanitizeObject<TEntity>(TEntity record)
        {
            var props =
                record.GetType().GetProperties()
                    .Where(x => x.CanRead && x.CanWrite)
                    .Where(x => x.PropertyType == typeof (string));
            foreach (var property in props)
            {
                string value = Convert.ToString(record.GetPropertyValue(property.Name));
                if (!string.IsNullOrEmpty(value))
                {
                    value = Sanitize(value);
                    record.SetPropertyValue(property.Name, value);
                }
            }
        }

在这种情况下,我将只清理Person.PersonName,但是,我还需要清理Address.StreetNameAddress.City

有没有办法编写这个 lambda 表达式来获取字符串类型的孩子的属性?我应该如何执行此操作以获取字符串类型的所有属性,以便对它们进行清理?

【问题讨论】:

  • 你有没有尝试过?我的意思是,您的清理对象可以分解为字符串和对象,然后在您的类包含的任何对象上调用相同的方法。
  • 即使您确实编写了一个 lambda 来做到这一点。你得问问你自己,任何人都可以阅读它吗?
  • 哈默斯坦,你是对的!我想我应该这样做!谢谢!

标签: c# reflection


【解决方案1】:

看来你需要一个递归方法。

伪代码:

public void SanitizeObject(object some)
{
    // We get properties which are of reference types because we don't want to iterate value types (do you want to sanitize an integer...?)
    foreach (PropertyInfo property in some.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(prop => !prop.PropertyType.IsValueType)
    {
        if (property.PropertyType == typeof (string))
        {
        // Do stuff to sanitize the string
        }
        else
        {
            // Get properties declared in the concrete class (skip inherited members)
            var properties = property.DeclaringType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);

            // Does the property type has properties?
            if (properties != null && properties.Length > 0)
            {
                // This gets the custom object and starts a recursion to sanitize its string properties if the object have string properties, of course...
                SanitizeObject(property.GetValue(some));
            }
        }
    }
}

请注意,我删除了泛型参数。我相信,由于您将使用反射来获取要清理的属性,因此使用泛型根本没有任何优势。使用这种方法,您将能够清理任何对象,而不仅仅是支持实体类型。

【讨论】:

  • 效果很好!谢谢!但是如果我有一个 List
    类型的属性呢?
  • @John 嘿,好吧,你需要做 property.GetValue 的事情,将其转换为 IEnumerable&lt;object&gt; 并为每个对象执行一次 foreach,并对每个对象进行递归
猜你喜欢
  • 2017-05-31
  • 2018-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
相关资源
最近更新 更多