1

我正在使用配置文件制作一个文件备份程序来保存设置等。目前的结构是这样的:

MainForm一个ProfileHandler有一堆配置文件对象

当您在程序中进行任何更改(将文件添加到列表、更改目标路径等)时 - 设置将保存在临时配置文件中。到现在为止还挺好...

但是当我想保存配置文件时,我真的无法决定要走哪条路。现在我将临时配置文件对象传递AddProfileProfileHandler. 然后该方法创建一个新的配置文件对象,使用临时配置文件对象的属性作为参数(a 除外List<string>,它只是使用 Addrange 复制内容)。

它有效,但它好吗?

public bool AddProfile(Profile tempProfile)
{
    if (tempProfile != null)
    {
        Profile profile = new Profile(tempProfile.Name, tempProfile.TargetPath);
        profile.Filelist.Clear();
        profile.Filelist.AddRange(tempProfile.Filelist);
        _profiles.Add(profile);
    }
    return (tempProfile != null);
}

有没有更巧妙的方法?不知何故,我觉得必须有一种简单的方法来创建一个新的Profile对象实例,它是tempProfile. 在我的例子中,这个Profile类只有三个字段,这很容易,但是如果它有很多呢?

我希望我不是太不清楚。我对此有点陌生。

4

3 回答 3

1

您可以制作您的深层副本tempProfile并保存。这是示例代码源代码如何在 .NET(特别是 C#)中对对象进行深层复制?

public static T DeepClone<T>(T obj)
{
 using (var ms = new MemoryStream())
 {
   var formatter = new BinaryFormatter();
   formatter.Serialize(ms, obj);
   ms.Position = 0;

   return (T) formatter.Deserialize(ms);
 }
}
于 2012-08-26T20:46:15.430 回答
1

只需创建一个接受 Profile 的构造函数并像这样进行复制:

public Profile(Profile profileToCreateFrom)
    : this(profileToCreateFrom.Name, profileToCreateFrom.TargetPath)
{
    FileList = profileToCreateFrom.FileList.Select(file => file).ToList();
}

然后你添加新的:

_profiles.Add(new Profile(tempProfile));
于 2012-08-26T20:51:39.813 回答
1

您可以查看受保护的object.MemberwiseClone方法。这种方法从早期就已经存在。

void Main()
{
    Profile p = new Profile("bob", @"c:\foo");
    p.FileList.Add("bar.txt");

    Profile copy = p.DeepCopy();
    copy.FileList.Clear();
    copy.FileList.Add("baz.log");

    p.Dump("p");
    copy.Dump("copy");
}

public class Profile
{
    public Profile(string name, string targetPath)
    {
        this.Name = name;
        this.TargetPath = targetPath;
        this.FileList = new List<string>();
    }

    public Profile DeepCopy()
    {
        Profile copy = (Profile)this.MemberwiseClone(); // this takes care of Name & TargetPath
        copy.FileList = new List<string>(this.FileList);
        return copy;
    }

    public string Name { get; private set; }
    public string TargetPath { get; private set; }
    public List<string> FileList { get; private set; }
}

您可以将其MemberwiseClone视为进行浅按位复制。这通常适用于 int、double、float 等值类型,甚至适用于字符串等不可变引用类型。但是,您需要像List<string>在配置文件类中一样制作可变引用类型的副本,以便副本的突变也不会改变原始引用类型。就维护而言,这是一条细线——如果添加新的可变属性,则必须记住在克隆发生后在深复制方法中进行复制。

根据您的设计,可能还有其他内容,例如您可能不想复制的事件注册。您可以将这些视为瞬态。如果您的应用程序是多线程的,您也需要小心,在复制过程中,您必须像在其他地方一样付出同样的痛苦来维护对象的完整性(例如获取锁。)

我没有性能数据。无论如何,无论你采取什么建议,你最适合自己做一些性能测试,看看它是否足够快。

于 2012-08-26T21:29:46.510 回答