迭代对象自己的字符串&修剪每个

时间:2010-07-11 07:46:11

标签: c# .net reflection trim

我有多个大对象,每个对象大约有60个字符串。我必须修剪所有这些字符串,我想这样做而不必去this.mystring = this.mystring.Trim()。相反,我正在寻找一种方法来自动让每个对象发现自己的字符串,然后执行操作。

我对反思有点了解,但还不够,但我认为这是可能的吗?

另外,我不确定这是否重要,但有些字符串属性是只读的(只有一个getter),因此必须跳过这些属性。

帮助?

4 个答案:

答案 0 :(得分:14)

嗯,很容易获得所有属性,并找出哪些是字符串和可写的。 LINQ让它变得更加容易。

var props = instance.GetType()
                    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                    // Ignore non-string properties
                    .Where(prop => prop.PropertyType == typeof(string))
                    // Ignore indexers
                    .Where(prop => prop.GetIndexParameters().Length == 0)
                    // Must be both readable and writable
                    .Where(prop => prop.CanWrite && prop.CanRead);

foreach (PropertyInfo prop in props)
{
    string value = (string) prop.GetValue(instance, null);
    if (value != null)
    {
        value = value.Trim();
        prop.SetValue(instance, value, null);
    }
}

如果修剪实际上有所不同,您可能只想设置属性,以避免复杂属性的冗余计算 - 或者它可能不是您的问题。

如有必要,有各种方法可以改善性能 - 例如:

  • 只需缓存每种类型的相关属性
  • 使用Delegate.CreateDelegate为getter和setter构建委托
  • 可能使用表达式树,虽然我不确定他们是否在这里提供帮助

我不会采取任何这些步骤,除非性能实际上是一个问题。

答案 1 :(得分:3)

类似的东西:

    foreach (PropertyInfo prop in obj.GetType().GetProperties(
        BindingFlags.Instance | BindingFlags.Public))
    {
        if (prop.CanRead && prop.CanWrite && prop.PropertyType == typeof(string)
            && (prop.GetIndexParameters().Length == 0)) // watch for indexers!
        {
            var s = (string)prop.GetValue(obj, null);
            if (!string.IsNullOrEmpty(s)) s = s.Trim();
            prop.SetValue(obj, s, null);
        }
    }

答案 2 :(得分:1)

没有必要在props-loop中检查IEnumerable,如果实际实例是IEnumerable,则会忽略props。已修复IEnumerable部分:

private void TrimWhitespace(object instance)
{
    if (instance != null)
    {
        if (instance is IEnumerable)
        {
            foreach (var item in (IEnumerable)instance)
            {
                TrimWhitespace(item);
            }
        }

        var props = instance.GetType()
                .GetProperties(BindingFlags.Instance | BindingFlags.Public)
            // Ignore indexers
                .Where(prop => prop.GetIndexParameters().Length == 0)
            // Must be both readable and writable
                .Where(prop => prop.CanWrite && prop.CanRead);

        foreach (PropertyInfo prop in props)
        {
            if (prop.GetValue(instance, null) is string)
            {
                string value = (string)prop.GetValue(instance, null);
                if (value != null)
                {
                    value = value.Trim();
                    prop.SetValue(instance, value, null);
                }
            }
            else 
                TrimWhitespace(prop.GetValue(instance, null));
        }
    }
}

答案 3 :(得分:0)

所以为了稍微扩展一下,我有一个带有Lists of Lists的复杂对象,我想遍历它并修剪所有子字符串对象。我发布了@Jon在答案中所做的事情。我很好奇是否有更好的方法,或者我错过了一些明显的东西。

我拥有的对象比这更复杂,但它应该说明我在尝试什么。

public class Customer
{
  public string Name { get; set; }
  public List<Contact> Contacts { get; set; }
}

public class Contact
{
  public string Name { get; set; }
  public List<Email> EmailAddresses {get; set;}
}

public class Email
{
  public string EmailAddress {get; set;}
}


    private void TrimWhitespace(object instance)
    {
        if (instance != null)
        {
            var props = instance.GetType()
                    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                // Ignore indexers
                    .Where(prop => prop.GetIndexParameters().Length == 0)
                // Must be both readable and writable
                    .Where(prop => prop.CanWrite && prop.CanRead);

            foreach (PropertyInfo prop in props)
            {
                if (instance is IEnumerable)
                {
                    foreach (var item in (IEnumerable)instance)
                    {
                        TrimWhitespace(item);
                    }
                }
                else if (prop.GetValue(instance, null) is string)
                {
                    string value = (string)prop.GetValue(instance, null);
                    if (value != null)
                    {
                        value = value.Trim();
                        prop.SetValue(instance, value, null);
                    }
                }
                else 
                    TrimWhitespace(prop.GetValue(instance, null));
            }
        }
    }

思想?