反射 trim 列表中的所有字符串与列表 c#

reflection trim all strings in list with list c#

我有一个方法 trim 第一级的所有字符串。

public static IEnumerable<T> Trim<T>(this IEnumerable<T> collection)
{
    foreach (var item in collection)
    {
        var stringProperties = item.GetType().GetProperties()
                  .Where(p => p.PropertyType == typeof(string));

        foreach (var stringProperty in stringProperties)
        {
            var currentValue = (string)stringProperty.GetValue(item, null);

            if (currentValue != null)
                stringProperty.SetValue(item, currentValue.Trim(), null);
        }
    }
    return collection;
}

但是如果我的 属性 是一个列表,我需要在此列表中的所有字符串属性中应用 trim,有人帮我吗?

public static IEnumerable<T> Trim<T>(this IEnumerable<T> collection)
    where T:class 
{
    foreach (var item in collection)
    {
        var properties = item.GetType().GetProperties();

        // Loop over properts
        foreach (var property in properties)
        {
            if (property.PropertyType == typeof (string))
            {
                var currentValue = (string)property.GetValue(item);
                if (currentValue != null)
                    property.SetValue(item, currentValue.Trim());
            }
            else if (typeof(IEnumerable<object>).IsAssignableFrom(property.PropertyType))
            {
                var currentValue = (IEnumerable<object>)property.GetValue(item);
                if (currentValue != null)
                    currentValue.Trim();
            }
        }
    }
    return collection;
}

编辑:包括收益

Edit2:再次删除了 yield。我知道这对 IEnumerable 扩展来说是不好的做法。但是替代方案是:

            else if (typeof(IEnumerable<object>).IsAssignableFrom(property.PropertyType))
            {
                var currentValue = (IEnumerable<object>)property.GetValue(item);
                if (currentValue != null)
                    currentValue.Trim().ToList(); // Hack to enumerate it!
            }
        }
    }
    yield return item;
}

假设您需要更改源集合中的字符串,如您的示例所示,那么我认为最简单的方法可能是添加一个额外的扩展方法来专门处理字符串列表,即反过来利用您示例中的扩展方法,将其更改为特定于字符串的 IEnumerables。新的扩展方法会非常简单,像这样:

public static IEnumerable<List<string>> Trim( this IEnumerable<List<string>> collection )
{
    foreach(var item in collection)
    {
        item.Trim();
    }
    return collection;
}

你的扩展会像这样调整:

public static IEnumerable<string> Trim( this IEnumerable<string> collection )
{
    foreach( var item in collection )
    {
        var stringProperties = item.GetType().GetProperties()
                    .Where( p => p.PropertyType == typeof( string ) );

        foreach( var stringProperty in stringProperties )
        {
            var currentValue = (string)stringProperty.GetValue( item, null );

            if( currentValue != null )
                stringProperty.SetValue( item, currentValue.Trim(), null );
        }
    }
    return collection;
}

我保留了您返回原始集合的模式,我想这是为了提供您想要的某种类型的方法链接。

当然,这不处理递归,但据我所知,这不是这里的要求。