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

时间:2016-01-07 13:08:25

标签: c# arrays list

我有一份文件清单

->

fullFilepath应该是List或Path of Arrays。

例如:

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

如果我使用数组字符串我的问题所有文档都得到了" null"在其fullFilePath中。 如果我使用List for fullFilePath,则所有Documents都从上一个Document获得相同的条目。

以下是列表的填写方式:

Document 1
 ---> C:\1.pdf
 ---> C:\2.pdf

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

2 个答案:

答案 0 :(得分:2)

您正在为每个文档使用相同的数组实例。在每个内部循环中使用新的文件列表更新实例,但是数组是对内存区域的引用(过度简化,我知道但是为了这个答案的目的就足够了)并且如果您更改该区域的内容您要为每个文档更改内存。

您需要为添加到文档列表中的每个新文档创建源文件的新实例。此外,当您不确定要包含在数组中的元素数量时,使用通用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);
}

请注意,当您需要添加新文档时,我构建一个新的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而无需检查列表初始化。

答案 1 :(得分:1)

问题应该在这里:

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