1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| using System; using System.Reflection; using System.Linq.Expressions;
public static List<string> selectToCsv<T>(this List<T> list, string delimiter) { Type source = typeof(T);
PropertyInfo[] prop = source.GetProperties();
ParameterExpression t = Expression.Parameter(source, "t");
MethodInfo toString = typeof(object).GetMethod("ToString");
List<ConditionalExpression> parameters = new List<ConditionalExpression>();
foreach (PropertyInfo p in prop) { MemberExpression propertyValue = Expression.PropertyOrField(t, p.Name);
MethodCallExpression propertyToString = Expression.Call(propertyValue, toString);
ConstantExpression constantNull = Expression.Constant(null, typeof(object));
BinaryExpression isNull = Expression.Equal(propertyToString, constantNull);
if (p.PropertyType == typeof(string)) { isNull = Expression.Equal(propertyValue, constantNull); }
ConstantExpression constantEmpty = Expression.Constant(string.Empty, typeof(string));
ConditionalExpression ternary = Expression.Condition(isNull, constantEmpty, propertyToString);
parameters.Add(ternary); } MethodInfo formatMethod = typeof(string).GetMethod("Format", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string), typeof(object[]) }, null); List<string> formatStrings = Enumerable.Range(0, prop.Length).Select(count => $"{{{count}}}").ToList();
ConstantExpression formatConstantExpression = Expression.Constant(string.Join(delimiter, formatStrings));
NewArrayExpression formatObjsExpression = Expression.NewArrayInit(typeof(string), parameters);
Expression<Func<T, string>> lambda = (Expression<Func<T, string>>)Expression.Lambda(Expression.Call(formatMethod, formatConstantExpression, formatObjsExpression), t);
IQueryable<T> queryable = list.AsQueryable();
return queryable.Select(lambda).ToList(); }
|