Search code examples
c#classdefensive-copy

Correct Way of Creating a Defensive Copy of Custom Class


I've got the following class:

public class FolderAgent
    {
        public string directoryName {get; private set; }
        public int numberofdirectories {get; private set; }
        public int numberofFiles {get; private set;}
        public DirectoryInfo [] directories {get; private set;}
        public FileInfo [] files {get; private set;}

        public FolderAgent(string directoryName, int numberofdirectories, int numberofFiles, DirectoryInfo [] listDir, FileInfo [] listFiles)
        {
            this.directoryName = directoryName;
            this.numberofdirectories = numberofdirectories;
            this.numberofFiles = numberofFiles;
            Array.Copy(listDir, directories, listDir.Length);
            Array.Copy(listFiles, files, listFiles.Length);
        }
    }

I have another class that will take folderagent as a parameter in the constructor, is this the correct way of creating a defensive copy of the Folderagent object?

public class FolderKey
    {

        public FolderAgent folder {get; private set;}
        public int returnValue {get; private set;}

        public FolderKey(FolderAgent folder, int returnValue)
        {
            this.folder = new FolderAgent(folder.directoryName, folder.numberofdirectories, folder.numberofFiles, folder.directories, folder.files);
            this.returnValue = returnValue;
        }
    }

Solution

  • You basically want a copy of all elements of the array. Note that FileInfo and DirectoryInfo use cached data which gets initialized the first time you access any of the file/directory properties.

    So you might just aswell recreate the objects, instead of making a copy... something like (untested):

    public FolderAgent(string directoryName, int numberofdirectories,
                       int numberofFiles, DirectoryInfo [] listDir, 
                       FileInfo [] listFiles)
    {
        this.directoryName = directoryName;
        this.numberofdirectories = numberofdirectories;
        this.numberofFiles = numberofFiles;
    
        directories = new DirectoryInfo[listDir.length];
        for(var i = 0; i < listDir.length; i++)
          directories[i] = new DirectoryInfo(listDir[i].FullName);
    
        files = new FileInfo[listFiles.length];
        for(var i = 0; i < listFiles.length; i++)
          files[i] = new FileInfo(listFiles[i].FullName);
    }