gpt4 book ai didi

c# - 在范围末尾执行清理的结构是一个好的 C# 模式吗?

转载 作者:行者123 更新时间:2023-12-05 07:32:19 25 4
gpt4 key购买 nike

RAII 非常适合确保您不会调用清理失败。通常,我会使用 来实现。我目前正在使用 Unity,并且意识到在 Update 中生成垃圾(甚至在编辑器脚本中)。我在想,为开始/结束操作创建一个 struct 包装器是避免分配的好模式吗? (自 value types don't allocate on the heap 以来。)

这是一个编辑器脚本示例:

public struct ActionOnDispose : IDisposable
{
Action m_OnDispose;
public ActionOnDispose(Action on_dispose)
{
m_OnDispose = on_dispose;
}

public void Dispose()
{
m_OnDispose();
}
}

EditorGUILayout是一种 Unity 类型,它公开了几个需要在代码前后调用的函数。我会像这样使用 ActionOnDispose:

public static ActionOnDispose ScrollViewScope(ref Vector2 scroll)
{
scroll = EditorGUILayout.BeginScrollView(scroll);
return new ActionOnDispose(EditorGUILayout.EndScrollView);
}

private Vector2 scroll;
public void OnGUI() // called every frame
{
using (EditorHelper.ScrollViewScope(ref scroll))
{
for (int i = 0; i < 1000; ++i)
{
GUILayout.Label("Item #"+ i);
}
}
}

上面的简单示例按预期工作,每次调用 ScrollViewScope 都会调用一次 Dispose,因此它看起来是正确的。 Unity 甚至提供了一个作用域结构:EditorGUI.DisabledScope ,但在很多情况下并非如此。所以我想知道这种结构模式是否有缺点? (我假设如果结构以某种方式被复制,旧的副本将被处置并且我的结束操作被调用两次?我没有看到这样的场景,但我对 C# 值类型不是很熟悉。)

编辑:我特别询问我使用结构(值类型)是否重要。 Is abusing IDisposable to benefit from “using” statements considered harmful涵盖这是否是对 IDisposable 的良好使用。

最佳答案

Jeroen Mostert 的评论作为回答:

Assigning does not generate the garbage, writing new ActionOnDispose(EditorGUILayout.EndScrollView) does. (Yes, this too allocates a new Action under water, it's just syntactic shorthand.) In general, it's very hard to avoid allocation if you're using delegates, but it usually doesn't pay off to do so either. Short-lived objects are collected in gen 0, which is very efficient. My uneducated guess would be that methods like EditorGUILayout.BeginScrollView are going to allocate stuff themselves, to the point where one more allocation on your end won't matter much.

To answer your other question, no, copying the struct would not cause the method to be called twice. The only way to do that is to actually have it wrapped in two different Dispose scopes. C# does not have RAII; things going out of scope does nothing. It's the using statement that does the actual magic.

我的结论:

我可以为每个用例制作 ActionOnDispose 版本,以避免使用产生垃圾的 Action。

关于c# - 在范围末尾执行清理的结构是一个好的 C# 模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51295732/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com