I have a variable defined as List<Car>. I want to concatenate the properties of the individual class in a list with some delimiter and write to file without looping on properties.
Example:
public class Car
{
public int CarId { get; set; }
public string Brand { get; set; }
public string Model { get; set; }
public string Color { get; set; }
}
public void AssignData()
{
List<Car> cars = new List<Car>();
cars.Add(new Car { CarId = 1, Brand = "Hundai", Model = "i10", Color = "White" });
cars.Add(new Car { CarId = 2, Brand = "Hundai", Model = "i20", Color = "Blue" });
}
My expected output would be a text file with "," as a delimiter.
Exected output:
1,Hundai,i10,White 2,Hundai,120,Blue
I have tried the below code using propertyinfo class, but i feel it is not effeicient as there is a nested loop
Below is the one which tried:
using (StreamWriter file = new StreamWriter(@"D:\WriteLines.txt", true))
{
foreach (Car car in allCars)
{
PropertyInfo[] properties = car.GetType().GetProperties();
string fullLine = string.Empty;
foreach (PropertyInfo property in properties)
{
fullLine += property.GetValue(car, null).ToString() + ",";
}
file.WriteLine(fullLine);
}
}
OK. Let's generalize the problem (see comments for the question): let us join all the properties which are:
public
and not static
. this[int, int]
property?).string
, int
, decimal
, double
) only (how can we save, a property of, say, IComparer<int>
type?).We can obtain such properties with a help of Reflection and Linq :
using System.Linq;
using System.Reflection;
...
HashSet<Type> allowedTypes = new HashSet<Type>() {
typeof(string), typeof(int), typeof(decimal), typeof(double)
};
var properties = typeof(Car)
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(prop => prop.CanRead && prop.CanWrite)
.Where(prop => !prop.GetIndexParameters().Any())
.Where(prop => allowedTypes.Contains(prop.PropertyType))
// .Where(prop => ...) // Add here more coditions if required
.ToArray();
Now, having these properties
we can save values into a file:
using System.IO;
using System.Linq;
...
File.WriteAllLines(@"D:\WriteLines.txt", cars
.Select(car => string.Join(",", properties
.Select(property => property.GetValue(car)))));
Finally, you can combine these parts into a single routine :
private static void SaveToFile<T>(IEnumerable<T> source, string fileName) {
HashSet<Type> allowedTypes = new HashSet<Type>() {
typeof(string), typeof(int), typeof(decimal), typeof(double)
};
var properties = typeof(T)
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(prop => prop.CanRead && prop.CanWrite)
.Where(prop => !prop.GetIndexParameters().Any())
.Where(prop => allowedTypes.Contains(prop.PropertyType))
// .Where(prop => ...) // Add here more coditions if required
.ToArray();
File.WriteAllLines(fileName, source
.Select(item => string.Join(",", properties
.Select(property => property.GetValue(item)))));
}
Then use it:
List<Car> cars = new List<Car>();
...
SaveToFile(Cars, @"D:\WriteLines.txt");
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.