为了账号安全,请及时绑定邮箱和手机立即绑定

在 C# 中,删除对象的 Action 会发生什么?

在 C# 中,删除对象的 Action 会发生什么?

PHP
一只萌萌小番薯 2024-01-21 10:05:50
我想为我的 TreeNode 类进行深度复制。这是我的代码:    public TreeNode(TreeNode node, GUIStyle inPointStyle, GUIStyle outPointStyle, Action<ConnectionPoint> OnClickInPoint, Action<ConnectionPoint> OnClickOutPoint){    this.rect = new Rect(node.rect);    this.style = new GUIStyle(node.style);    this.inPoint = new ConnectionPoint(this, ConnectionPointType.In, inPointStyle, OnClickInPoint);    this.outPoint = new ConnectionPoint(this, ConnectionPointType.Out, outPointStyle, OnClickOutPoint);    this.defaultNodeStyle = new GUIStyle(node.defaultNodeStyle);    this.selectedNodeStyle = new GUIStyle(node.selectedNodeStyle);    this.allDecorations = new List<GameObject>(node.allDecorations);    this.objs = new Dictionary<GameObject, IndividualSettings>(node.objs);    this.name = String.Copy(node.name);    this.RemoveClonedObj = new Action(node.RemoveClonedObj);    this.OnChangeView = new Action<TreeNode>(node.OnChangeView);    this.OnRemoveNode =  new Action<TreeNode>(node.OnRemoveNode);    this.OnCopyNode = new Action<TreeNode>(node.OnCopyNode);    this.PreviewTree = new Action<TreeNode, bool> (node.PreviewTree);}然而,骑士给了我警告:看来骑士是在说我的“新”毫无意义。如果我遵循 Rider 的指示,this.RemoveClonedObj = node.RemoveClonedObj;在删除原始 TreeNode 后,使用我复制的 TreeNode 的操作会发生什么?他们也会被移除吗?如果是这样,为什么 Rider 会给我这样的警告?
查看完整描述

2 回答

?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

在 C# 2.0 或更高版本中,以下代码是等效的(DelegateType是委托类型,顾名思义):

newDelegate = new DelegateType(oldDelegate);
newDelegate = oldDelegate;

此类操作将始终创建 的新实例DelegateType,该实例与oldDelegate. 它们并不引用同一个对象(不要被=赋值所混淆):

new D(E) 形式的 delegate_creation_expression(其中 D 是 delegate_type,E 是表达式)的绑定时处理由以下步骤组成:

  • 如果 E 是方法组,则委托创建表达式的处理方式与从 E 到 D 的方法组转换(Method group conversions)相同。

  • 如果 E 是匿名函数,则委托创建表达式的处理方式与从 E 到 D 的匿名函数转换(匿名函数转换)相同。

  • 如果 E 是一个值,则 E 必须与 D 兼容(委托声明),并且结果是对新创建的 D 类型委托的引用,该委托引用与 E 相同的调用列表。如果 E 与 D 不兼容,则会发生编译时错误。

所以关于你的问题

删除原始 TreeNode 后,我复制的 TreeNode 的操作会发生什么?他们也会被移除吗?

他们不会有什么事。它们不会被删除。


顺便说一句,由于您正在尝试对树节点进行深层复制,因此我怀疑这是否是正确的方法。尽管您创建了委托的新实例,但与其关联的类实例(将调用成员方法的实例)保持不变。


查看完整回答
反对 回复 2024-01-21
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

不要将实例方法相互链接。这会导致内存泄漏。


即使在原始节点被删除并且代码不再需要之后,由于副本的引用,原始实例将存在于内存中并且不会被垃圾收集。


我怀疑这不是你想要的,测试代码


class Program

{

    static void Main(string[] args)

    {

        First t = new First();

        Second s = new Second();

        t.Print = s.TestMethod;

        s.test = "change";

        s = null;

        t.Print("Hell"); // can debug and see that the function call goes through and string test is = "change"

    }

}


public class First

{

    public string s;

    public Action<string> Print;

}

public class Second

{

    public string test = "created";

    public void TestMethod (string test)

    {

        var res = "hello" + test + test;

    }

}

节点上的方法应该是 Node 对象的一部分,这样您就不必将它们分配给新节点,或者它们应该位于单独的类中,最好是静态的,以便创建新节点不会导致内存问题。


查看完整回答
反对 回复 2024-01-21
  • 2 回答
  • 0 关注
  • 68 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信