C# 以树状视图形式在文本文件中写入项目列表的最佳方法是什么

C# 以树状视图形式在文本文件中写入项目列表的最佳方法是什么,c#,C#,我有一个对象列表,每个对象都有一个从属对象列表,我想把列表写在树视图形式的文本文件中 我试着在列表中使用foreach,但我无法确定所有依赖项和对象的正确级别 //the list of all objects List<Object> objects; //object Class class Object { string name; List<Object> depandantObj; } 首先使用嵌套列表表单创建对象。例如: public

我有一个对象列表,每个对象都有一个从属对象列表,我想把列表写在树视图形式的文本文件中

我试着在列表中使用foreach,但我无法确定所有依赖项和对象的正确级别

//the list of all objects
List<Object> objects; 

//object Class
class Object {
    string name;
    List<Object> depandantObj;
}

首先使用嵌套列表表单创建对象。例如:

 public class MyObject{
   // some properties here 
 }
 public class MySecondObject{
   List<MyObject> {get; set;}
 }
  public class MythirdObject{
   List<MySecondObject> {get; set;}
 }
当您想将数据保存到一个文件时,只要将它们序列化为json,它就会为您创建一个可读的json文件

// I assume you can create your data or fetch them
var data = List<MyThirdObject> ();
string json = JsonConvert.SerializeObject(_data);

//write string to file
System.IO.File.WriteAllText(@"D:\path.txt", json);
如果您不需要json,那么可以创建一个递归方法,将每个对象添加到最后一个对象下。
看看如何以这种方式实现这一点。

考虑使用json,从Nuget下载dll

代码示例:

public class MyObject
{
   public string Name { get; set; }
}
public class MySecondObject
{
   public List<MyObject> DepObj { get; set; } = new List<MyObject>();
}
MyObject obj = new MyObject
{
    Name = "example"
};
MySecondObject mySecond = new MySecondObject();
mySecond.DepObj.Add(obj);
var data = new List<MySecondObject>
{
   mySecond
};
string json = JsonConvert.SerializeObject(data, Formatting.Indented);

System.IO.File.WriteAllText(@"D:\file.txt", json);

使用递归方法为每个具有缩进的对象追加新行:

public string GetText(Object obj, int indentLevel)
{
   string text = "";

   string indentation = new string(' ', indentLevel * 8);

   text += indentation + obj.name;

   if (obj.depandantObj != null && obj.depandantObj.Count > 0)
   {
      indentLevel++;
      foreach (Object o in obj.depandantObj)
      {
        text += Environment.NewLine + GetText(o, indentLevel);
       }
    }
    else
       return text;

    return text;
 }
调用列表中每个对象的方法,并将文本写入末尾的文本文件:

确保对象类中的字段name和depandantObj都是公共的

首先,让我们详细说明初始对象类;我已将其重命名,以避免与System.Object冲突,使字段公开,添加构造函数:

class MyObject {
  public string name = "";
  public List<MyObject> depandantObj = new List<MyObject>();

  public MyObject(string value, params MyObject[] dependent) {
    name = value;

    if (dependent != null)
      foreach (var item in dependent)
        depandantObj.Add(item);
  }
}

递归遍历ECHACT列表,在每一个新的级别添加缩进。您可以使用递归打印函数,在其中传递增加的深度参数。考虑使用JSON结构编写JSON文件。
public string GetText(Object obj, int indentLevel)
{
   string text = "";

   string indentation = new string(' ', indentLevel * 8);

   text += indentation + obj.name;

   if (obj.depandantObj != null && obj.depandantObj.Count > 0)
   {
      indentLevel++;
      foreach (Object o in obj.depandantObj)
      {
        text += Environment.NewLine + GetText(o, indentLevel);
       }
    }
    else
       return text;

    return text;
 }
List<Object> objects;

//add items to list
...

if(objects != null)
{
  string text = "";

  foreach (Object obj in objects)
  {
    text += GetText(obj, 0);
  }

  File.WriteAllText(Server.MapPath("~/sample.txt"), text);
}
class MyObject {
  public string name = "";
  public List<MyObject> depandantObj = new List<MyObject>();

  public MyObject(string value, params MyObject[] dependent) {
    name = value;

    if (dependent != null)
      foreach (var item in dependent)
        depandantObj.Add(item);
  }
}
private static IEnumerable<string> MyObjectToTree(IEnumerable<MyObject> roots, int shift = 6) {
  if (null == roots)
    yield break;

  foreach (var root in roots) {
    // We don't want infinte loop if objects create a cycle  
    HashSet<MyObject> completed = new HashSet<MyObject>();
    Stack<Tuple<int, MyObject>> agenda = new Stack<Tuple<int, MyObject>>();

    agenda.Push(Tuple.Create(0, root));

    while (agenda.Any()) {
      Tuple<int, MyObject> item = agenda.Pop();

      if (!completed.Add(item.Item2))
        continue;

      List<MyObject> children = item.Item2?.depandantObj ?? new List<MyObject>();

      children.Reverse();

      yield return $"{new string(' ', shift * item.Item1)}{item.Item2?.name}{(children.Any() ? ":" : "")}";

      foreach (var child in children)
        agenda.Push(Tuple.Create(item.Item1 + 1, child));
    }
  }
}
  // I've added the MyObject constructor for this readable creation
  List<MyObject> objects = new List<MyObject>() {
    new MyObject("object1", 
      new MyObject("object2"),
      new MyObject("object3",
        new MyObject("object4"),
        new MyObject("object5"))),
    new MyObject("object6",
      new MyObject("object2")),
  };

  foreach (string line in MyObjectToTree(objects, 6))
    Console.WriteLine(line);

  // If you want to write into file:
  // File.WriteAllLines(@"c:\MyFile.txt", MyObjectToTree(objects, 6));
object1:
      object2
      object3:
            object4
            object5
object6:
      object2