【问题标题】:C# assign one reference type to another without it's reference to the objectC# 将一种引用类型分配给另一种引用类型而不引用对象
【发布时间】:2013-03-28 10:09:25
【问题描述】:

我可以给引用类型赋值而不给它对该对象的引用吗? 就像我有获取文件信息的函数一样,我想检查一下稍后在不同的线程中是否发生了变化。

例子

info = GetInfo(path);
checkInfo=info; // I make changes to info later, but I wanna checkInfo to remain the same

【问题讨论】:

标签: c# .net multithreading winforms assign


【解决方案1】:

据我了解您的问题,您需要创建信息对象的深层副本

这是solution(使用序列化)

像这样创建扩展方法:

public static class ExtensionMethods
{
    // Deep clone
    public static T DeepClone<T>(this T a)
    {
        using (MemoryStream stream = new MemoryStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, a);
            stream.Position = 0;
            return (T) formatter.Deserialize(stream);
        }
    }
}

使用它:

checkInfo = info.DeepClone();

P.S 通常,需要深度克隆意味着需要代码重构。不一定,但经常发生......我认为在你的情况下应该有比复制对象更好的解决方案。

【讨论】:

  • +1 用于序列化/反序列化方法。我想也可以使用 AutoMapper,但我认为序列化方法更安全。
  • 当然,权衡是类型必须是可序列化的,如果支持泛型克隆是使其可序列化的唯一原因,这可以被认为是代码异味。
  • 添加了 P.S 部分。我完全同意关于“代码气味”的观点。一般来说,深度复制应该没有理由,只有在非常特殊的情况下
  • 同意。事实上,每当您认为需要克隆时,您首先应该考虑值类型而不是引用类型是否更合适。
  • 原始问题可能是您关于代码重构的一个很好的例子。名为 GetInfo() 的东西听起来像是返回的东西无论如何都应该被视为不可变的。
【解决方案2】:

您要么需要克隆 info 变量,要么需要重新分配它。手动克隆它需要相当多的工作,而且可能很脆弱,所以我推荐这样的东西:

checkInfo = info:
info = GetInfo(path);

另一个选项,如果您在到达这里之前没有更改 info 变量,则可以使用 GetInfo 设置 checkInfo。考虑这样一个事实,如果是这种情况,GetInfo 将为两者构建相同的对象,因此您将获得相同的结果。

【讨论】:

    【解决方案3】:

    您可以在另一个类中隐藏/包装您的 FileInfo 类,并让其他线程仅访问包装类。包装类可以触发事件,例如当其他线程更改 FileInfo 时 FileInfoChanged。

    【讨论】:

      猜你喜欢
      • 2018-01-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-28
      • 1970-01-01
      • 2015-07-26
      • 2011-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多