首页 > 解决方案 > 连接列表的属性并在 C# 中写入文件

问题描述

我有一个变量定义为 List<Car>。我想用一些分隔符连接列表中单个类的属性并写入文件而不循环属性。

例子:

    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" });
    }

我的预期输出将是一个带有“,”作为分隔符的文本文件。

执行输出:

1,Hundai,i10,White 2,Hundai,120,Blue

我已经使用 propertyinfo 类尝试了下面的代码,但我觉得它没有效率,因为有一个嵌套循环

以下是尝试过的:

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);
                }
            }

标签: c#concatenation

解决方案


好的。让我们概括一下这个问题(请参阅问题的评论):让我们加入所有属性

  1. public不是 static
  2. 可读
  3. 不是索引器(我们应该如何处理this[int, int]财产?)。
  4. 仅限指定类型(例如string, int, decimal, double)(我们如何保存,例如IComparer<int>类型的属性?)。

我们可以借助ReflectionLinq获得这些属性:

  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();

现在,有了这些,properties我们可以将值保存到文件中:

  using System.IO;
  using System.Linq;

  ...

  File.WriteAllLines(@"D:\WriteLines.txt", cars
    .Select(car => string.Join(",", properties
       .Select(property => property.GetValue(car)))));

最后,您可以将这些部分组合成一个例程

  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))))); 
  } 

然后使用它:

  List<Car> cars = new List<Car>();

  ... 

  SaveToFile(Cars, @"D:\WriteLines.txt");

推荐阅读