【问题标题】:Is it possible to make an noncopyable type in C#是否可以在 C# 中创建不可复制的类型
【发布时间】:2016-05-04 11:44:12
【问题描述】:

是否有可能在 C# 中创建一个无法复制而只能通过引用传递的类?

C++ 中的等价物是删除复制构造函数和复制赋值运算符。

【问题讨论】:

  • 类通过引用传递。
  • 我认为你不能复制一个对象,除非它实现了ICloneable 接口
  • 它将复制引用。还有一个对象。
  • @Knitschi 然后他们会指向同一个对象,如果你愿意,复制引用。
  • 试试看...正如@mikeyq6 已经说过的:类是通过引用传递的。

标签: c# noncopyable


【解决方案1】:

这是默认行为。如果你有课:

class foo {
    public string bar { get; set; }
}

在某处你可以这样做:

foo f1 = new foo();
foo f2 = f1;

f1f2 都将引用同一个实例。例如,如果您设置f1.bar = "bar",则从f2.bar 读取的值将是"bar"

【讨论】:

  • 所以我可以确定无论我用它做什么,类类型对象的析构函数只会被调用一次?
  • @Knitschi - C# 对象没有析构函数。最接近的是finalisers,大多数类也没有定义。
  • 我投了这个作为答案,但想指出您可以使用序列化复制对象,例如使用 Json.Net:foo f2 = JsonConvert.DeserializeObject<foo>(JsonConvert.SerializeObject(f1)); 这显然超出了问题的范围;我只是出于好奇而提到它。
  • 好吧,我的评论很愚蠢。每个对象只能被销毁一次。
  • 当对象被 GC 销毁时,只有垃圾收集器才会调用析构函数。但是,如果你有继承类并且它和基类都有析构函数,它们都会被调用。详情请查看msdn.microsoft.com/en-us/library/66x5fx1b.aspx
【解决方案2】:

您可以创建一个内部构造函数。这样,构造函数只能从定义它的程序集中调用。

您还可以通过使用 Reflection 和 StackTrace(例如)创建更高级的逻辑,并详细控制允许谁创建类的实例以及何时创建。类似的逻辑可以应用于属性,您可以在其中控制允许谁更改属性值。

【讨论】:

    【解决方案3】:

    C# 中没有析构函数,只有终结器。然而,GC 足够聪明,可以知道给定对象何时不再存在引用,然后调用此终结器。因此,当两个变量引用同一个对象时,只要这两个引用存在,这个对象就会存在。如果两个 (!!) 都超出范围,则 GC 收集对象以进行删除。

    【讨论】:

      猜你喜欢
      • 2020-03-31
      • 2021-10-20
      • 1970-01-01
      • 2022-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      相关资源
      最近更新 更多