Reputation: 953
I have a method with trim all strings in first level.
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;
}
But if my property is a List I need apply trim in all string properties in this list, someone help me?
Upvotes: 3
Views: 1939
Reputation: 331
Assuming you need to alter the strings in place in the source collection(s), as shown in your example, then I think the simplest approach might be to add an additional extension method to specifically handle Lists of strings, that in turn utilizes the extension method from your example, altered to be specific to IEnumerables of strings. The new extension method would be pretty simple, like so:
public static IEnumerable<List<string>> Trim( this IEnumerable<List<string>> collection )
{
foreach(var item in collection)
{
item.Trim();
}
return collection;
}
And your extension would get tweaked like so:
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;
}
I kept your pattern of returning the original collection, I assume this is to provide some type of method chaining that you desire.
Of course, this does not handle recursion but from what I've seen that isn't a requirement here.
Upvotes: 0
Reputation: 2398
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;
}
Edit: Included yield
Edit2: Removed yield again. I know this is bad practice for IEnumerable extensions. However the alternative would be:
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;
}
Upvotes: 4