在 C# 中,删除对象的 Action 会发生什么?
In C#, what will happen for an removed object's Action?
我想为我的 Class 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好像在说我的"new"没有意义。
如果我按照 Rider 的指示,使用 this.RemoveClonedObj = node.RemoveClonedObj;
删除原始 TreeNode 后我复制的 TreeNode 的 Actions 会发生什么?它们也会被移除吗?如果是,为什么Rider给我这样的警告?
不要link彼此实例方法。这将导致内存泄漏。
即使删除了原始节点并且您的代码不再需要该节点,由于来自副本的引用,原始实例仍将存在于内存中并且不会被垃圾收集。
我怀疑这不是你想要的,为此测试代码
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 对象的一部分,这样你就不必将它们分配给新节点,要么它们应该在一个单独的 class 中,最好是静态的,这样创建新节点不会导致内存问题。
在C# 2.0及以上版本中,以下代码是等价的(DelegateType
顾名思义是委托类型):
newDelegate = new DelegateType(oldDelegate);
newDelegate = oldDelegate;
(见MSDN - How to: Declare, Instantiate, and Use a Delegate (C# Programming Guide))
此外,Microsoft 指定(参见 here)此类操作将始终创建 DelegateType
的 新实例,它具有与oldDelegate
。它们不引用同一个对象(不要被 =
赋值混淆):
The binding-time processing of a delegate_creation_expression of the form new D(E), where D is a delegate_type and E is an expression, consists of the following steps:
If E is a method group, the delegate creation expression is processed in the same way as a method group conversion (Method group conversions) from E to D.
If E is an anonymous function, the delegate creation expression is processed in the same way as an anonymous function conversion (Anonymous function conversions) from E to D.
If E is a value, E must be compatible (Delegate declarations) with D, and the result is a reference to a newly created delegate of type D that refers to the same invocation list as E. If E is not compatible with D, a compile-time error occurs.
所以关于你的问题
What will happen for my copyed TreeNode's Actions aftering removing the orginal TreeNode? Will they be removed as well?
他们不会有事的。它们不会被删除。
顺便说一句,由于您正在尝试对树节点进行深拷贝,我怀疑这是否是正确的方法。尽管您已经创建了委托的新实例,但与其关联的 class 实例(将调用成员方法的实例)保持不变。
我想为我的 Class 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好像在说我的"new"没有意义。
如果我按照 Rider 的指示,使用 this.RemoveClonedObj = node.RemoveClonedObj;
删除原始 TreeNode 后我复制的 TreeNode 的 Actions 会发生什么?它们也会被移除吗?如果是,为什么Rider给我这样的警告?
不要link彼此实例方法。这将导致内存泄漏。
即使删除了原始节点并且您的代码不再需要该节点,由于来自副本的引用,原始实例仍将存在于内存中并且不会被垃圾收集。
我怀疑这不是你想要的,为此测试代码
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 对象的一部分,这样你就不必将它们分配给新节点,要么它们应该在一个单独的 class 中,最好是静态的,这样创建新节点不会导致内存问题。
在C# 2.0及以上版本中,以下代码是等价的(DelegateType
顾名思义是委托类型):
newDelegate = new DelegateType(oldDelegate);
newDelegate = oldDelegate;
(见MSDN - How to: Declare, Instantiate, and Use a Delegate (C# Programming Guide))
此外,Microsoft 指定(参见 here)此类操作将始终创建 DelegateType
的 新实例,它具有与oldDelegate
。它们不引用同一个对象(不要被 =
赋值混淆):
The binding-time processing of a delegate_creation_expression of the form new D(E), where D is a delegate_type and E is an expression, consists of the following steps:
If E is a method group, the delegate creation expression is processed in the same way as a method group conversion (Method group conversions) from E to D.
If E is an anonymous function, the delegate creation expression is processed in the same way as an anonymous function conversion (Anonymous function conversions) from E to D.
If E is a value, E must be compatible (Delegate declarations) with D, and the result is a reference to a newly created delegate of type D that refers to the same invocation list as E. If E is not compatible with D, a compile-time error occurs.
所以关于你的问题
What will happen for my copyed TreeNode's Actions aftering removing the orginal TreeNode? Will they be removed as well?
他们不会有事的。它们不会被删除。
顺便说一句,由于您正在尝试对树节点进行深拷贝,我怀疑这是否是正确的方法。尽管您已经创建了委托的新实例,但与其关联的 class 实例(将调用成员方法的实例)保持不变。