C#将数组或列表添加到列表中

本文关键字:列表 添加 数组 | 更新日期: 2023-09-27 18:29:31

我有一个文档列表

public class Document
{
    public string[] fullFilePath;
    public bool isPatch;
    public string destPath;

    public Document() { }
    public Document(string[] fullFilePath, bool isPatch, string destPath)
    {
        this.fullFilePath = fullFilePath;
        this.isPatch = isPatch;
        this.destPath = destPath;
    }

fullFilepath应该是List或Array of Paths。

例如:

Document 1
 ---> C:'1.pdf
 ---> C:'2.pdf
Document 2
 ---> C:'1.pdf
 ---> C:'2.pdf
 ---> C:'3.pdf

等等。

我的问题是,如果我使用一个数组字符串,所有文档在其fullFilePath中都为"null"。如果我使用列表作为fullFilePath,那么所有文档都会从上一个文档中获得相同的条目。

以下是列表的填写方式:

            int docCount = -1;
            int i = 0;

            List<Document> Documents = new List<Document>();
            string[] sourceFiles = new string[1];
            foreach (string file in filesCollected)
            {
                string bc;
                string bcValue;

                if (Settings.Default.barcodeEngine == "Leadtools")
                {
                    bc = BarcodeReader.ReadBarcodeSymbology(file);
                    bcValue = "PatchCode";
                }
                else
                {
                    bc = BarcodeReader.ReadBacrodes(file);
                    bcValue = "009";
                }
                if (bc == bcValue)
                {
                    if(Documents.Count > 0)
                    {
                         Array.Clear(sourceFiles, 0, sourceFiles.Length);
                         Array.Resize<string>(ref sourceFiles, 1);
                         i = 0;
                    }
                    sourceFiles[i] =  file ;
                    i++;
                    Array.Resize<string>(ref sourceFiles, i + 1);
                    Documents.Add(new Document(sourceFiles, true,""));
                    docCount++;

                }
                else
                {
                    if (Documents.Count > 0)
                    {
                        sourceFiles[i] = file;
                        i++;
                        Array.Resize<string>(ref sourceFiles, i + 1);
                        Documents[docCount].fullFilePath = sourceFiles;
                    }
                }                
            }

C#将数组或列表添加到列表中

您为每个文档使用相同的数组实例。实例在每个内部循环中都会更新一个新的文件列表,但数组是对内存区域的引用(我知道过于简单化,但就这个答案而言就足够了),如果您更改该内存区域的内容,那么您就是在为每个文档更改它。

您需要为添加到文档列表中的每个新文档创建源文件的新实例。此外,当您不确定要包含在数组中的元素数量时,最好使用泛型List并删除所有处理数组大小调整的代码。

首先更改类定义

public class Document
{
    public List<string> fullFilePath;
    public bool isPatch;
    public string destPath;

    public Document() { }
    public Document(List<string> fullFilePath, bool isPatch, string destPath)
    {
        this.fullFilePath = fullFilePath;
        this.isPatch = isPatch;
        this.destPath = destPath;
    }
}

现在将你的内环改为

foreach (string file in filesCollected)
{
    string bc;
    string bcValue;
    ....
    if (bc == bcValue)
    {
        List<string> files = new List<string>();
        files.Add(file);
        Documents.Add(new Document(files, true, ""));
        docCount++;
    }
    else
        Documents[docCount].fullFilePath.Add(file);
}

请注意,当您需要添加新的Document时,我会构建一个新的List<string>,添加当前文件并在构造函数中传递所有内容(实际上,这应该直接移动到Document类的构造函数中)。当您只想添加一个新文件时,可以直接将其添加到公共fullFilePath属性

移动Documents类中的文件处理可以重写为

public class Document
{
    public List<string> fullFilePath;
    public bool isPatch;
    public string destPath;
    public Document() 
    {
         // Every constructory initializes internally the List
         fullFilePath = new List<string>(); 
    }
    public Document(string aFile, bool isPatch, string destPath)
    {
        // Every constructory initializes internally the List
        fullFilePath = new List<string>(); 
        this.fullFilePath.Add(aFile);
        this.isPatch = isPatch;
        this.destPath = destPath;
    }
    public void AddFile(string aFile)
    {
        this.fullFilePath.Add(aFile);
    }
}

当然,现在在调用代码时,只传递新文件或调用AddFile,而不需要检查列表初始化。

问题应该在这里:

string[] sourceFiles = new string[1];

如果你在foreach中移动这行代码,你应该解决这个问题,因为在foreach里你总是使用相同的变量,所以使用相同的引用。

int docCount = -1;
int i = 0;
List<Document> Documents = new List<Document>();
foreach (string file in filesCollected)
{
    string[] sourceFiles = new string[1];
    string bc;
    string bcValue;
    if (Settings.Default.barcodeEngine == "Leadtools")
    {
        bc = BarcodeReader.ReadBarcodeSymbology(file);
        bcValue = "PatchCode";
    }
    else
    {
        bc = BarcodeReader.ReadBacrodes(file);
        bcValue = "009";
    }
    if (bc == bcValue)
    {
        if(Documents.Count > 0)
        {
            Array.Clear(sourceFiles, 0, sourceFiles.Length);
            Array.Resize<string>(ref sourceFiles, 1);
            i = 0;
        }
        sourceFiles[i] =  file ;
        i++;
        Array.Resize<string>(ref sourceFiles, i + 1);
        Documents.Add(new Document(sourceFiles, true,""));
        docCount++;
    }
    else
    {
        if (Documents.Count > 0)
        {
            sourceFiles[i] = file;
            i++;
            Array.Resize<string>(ref sourceFiles, i + 1);
            Documents[docCount].fullFilePath = sourceFiles;
        }
    }                
}