简体   繁体   中英

Create csv based on a object property assigned dynamically

I need to build a csv string based on a specific property from an object stored in a list but I've got to do this for multiple properties:

The below works fine when "hardcoded":

var list = customers.Select(p => p.Email).ToArray();
csvString = string.Join(";", list1);

but I obviously don't want to have to do this for every property I need. Is there a way for me to build a function and assign the property name I want to use to one of the parameters. Something similar to this:

var emails = ConvertCollectionToCsv(customers, "Email");
var names = ConvertCollectionToCsv(customers, "Name");
var mobile = ConvertCollectionToCsv(customers, "Mobile");
...

I thought I'd try the following:

private string ConvertCollectionToCsv(List<Customer> customers, string propertyName)
{
   var prop = typeof(EmailAddress).GetProperties().FirstOrDefault
   (p => p.Name.ToLowerInvariant() == propertyName.ToLowerInvariant());

   var list = customers.Select(p => prop.Name).ToArray();
   return string.Join(";", list);
}

but when called:

var emails = ConvertCollectionToCsv(customers, "Email");

it returns Email;Email;Email instead of the email address which makes sense as the prop.Name is used. I'm trying to use the GetValue instead:

var list = customers.Select(p => prop.GetValue(p)).ToArray();

but that's throwing the following error:

"Object does not match target type."

Any suggestions?

Thanks

You have to get the properties from the Customer, since that is were you get the value later on.

var prop = typeof(Customer).GetProperties().FirstOrDefault
(p => p.Name.ToLowerInvariant() == propertyName.ToLowerInvariant());

and this seems odd:

var list = list.Select(p => prop.GetValue(p)).ToArray();

list.Select - what is list? isn't it rather:

var list = customers.Select(p => prop.GetValue(p)).ToArray();

You are passing a List of Customer -objects to the method but use a property of EmailAddress , these types don't match.

I'd suggest a generic method here:

private string ConvertCollectionToCsv<T>(IEnumerable<T> items, string propertyName)
{
   var prop = typeof(T).GetProperties().FirstOrDefault
   (p => p.Name.ToLowerInvariant() == propertyName.ToLowerInvariant());

   var list = items.Select(p => prop.GetValue(p)).ToArray();
   return string.Join(";", list);
}

This way, you pass in any collection, eg a List<string> or an array like MyCustomType[]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM