C# 处理图形对象
我被处理图形对象的机械原理弄糊涂了。处理字体和笔等对象的最佳方法是什么?在实例化/处置它们时,最好的做法是什么?我的意思是类中的字段还是方法中的变量 例如,我有一个类似以下代码的类。我有一些字体和笔,它们在类中的每个地方都使用,所以我不是每次在调用方法时都创建它们,而是将它们创建为字段。这会提高性能吗C# 处理图形对象,c#,winforms,graphics,dispose,idisposable,C#,Winforms,Graphics,Dispose,Idisposable,我被处理图形对象的机械原理弄糊涂了。处理字体和笔等对象的最佳方法是什么?在实例化/处置它们时,最好的做法是什么?我的意思是类中的字段还是方法中的变量 例如,我有一个类似以下代码的类。我有一些字体和笔,它们在类中的每个地方都使用,所以我不是每次在调用方法时都创建它们,而是将它们创建为字段。这会提高性能吗 public class PackageDrawer : IDisposable { Font font1 = .... Font font2 = .... Font font3
public class PackageDrawer : IDisposable
{
Font font1 = ....
Font font2 = ....
Font font3 = ....
Pen pen1 = ...
Pen pen2 = ...
Pen pen3 = ...
public Bitmap Draw()
{
//use fonts and pens here
//also they are being user in more methods
}
~PackageDrawer()
{
Dispose();
}
public void Dispose()
{
font1.Dispose();
//And dispose other stuff...
}
}
一般来说,
画笔
,画笔
对象的分配越晚越好,而处理(…)
越快越好。通常在主(假设的)Paint(…)
方法中处理。这就是几乎所有框架中的绘图工件(并且.NET
也不例外)都像结构一样声明,以保证堆栈上的快速分配和快速销毁 一般来说,Pen
,Brush
对象最好尽可能晚地分配,并且Dispose(…)
越快越好。通常在主(假设的)Paint(…)
方法中处理。这就是几乎所有框架中的绘图工件(并且.NET
也不例外)都像结构一样声明,以保证堆栈上的快速分配和快速销毁
处理字体和笔等对象的最佳方法是什么
最好也是唯一的方法是调用Dispose()
当您不再需要它们时,您应该将它们处理掉
在实例化/处置它们时,最好的做法是什么
这一切都取决于您的实现。在大多数情况下,最好在处理完它们后立即创建和销毁它们。这一切实际上取决于客户端代码如何实现PackageDrawer
对象以及可能访问这些对象的方法
您可能需要阅读StackOverflow上的IDisposable
。从您发布的内容中,您可以删除~PackageDrawer()
终结器覆盖,只需创建一个Dispose()
方法即可。如果从该方法派生任何类,您可能还希望将Dispose
方法设置为虚拟
此外,没有任何东西阻止在对象上多次调用Dispose()
,因此您需要添加一个私有跟踪布尔值,以确保它不会多次尝试和Dispose()
。另外,在尝试调用Dispose()
之前,请始终对对象执行null检查,以避免出现NullReferenceException
private bool _isDisposed;
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (_isDisposed)
return;
if (disposing)
{
if (font != null)
font.Dispose();
}
_isDisposed = true;
}
处理字体和笔等对象的最佳方法是什么
最好也是唯一的方法是调用Dispose()
当您不再需要它们时,您应该将它们处理掉
在实例化/处置它们时,最好的做法是什么
这一切都取决于您的实现。在大多数情况下,最好在处理完它们后立即创建和销毁它们。这一切实际上取决于客户端代码如何实现PackageDrawer
对象以及可能访问这些对象的方法
您可能需要阅读StackOverflow上的IDisposable
。从您发布的内容中,您可以删除~PackageDrawer()
终结器覆盖,只需创建一个Dispose()
方法即可。如果从该方法派生任何类,您可能还希望将Dispose
方法设置为虚拟
此外,没有任何东西阻止在对象上多次调用Dispose()
,因此您需要添加一个私有跟踪布尔值,以确保它不会多次尝试和Dispose()
。另外,在尝试调用Dispose()
之前,请始终对对象执行null检查,以避免出现NullReferenceException
private bool _isDisposed;
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (_isDisposed)
return;
if (disposing)
{
if (font != null)
font.Dispose();
}
_isDisposed = true;
}
您不需要定稿人,也不应该使用它来调用Dispose
,因为无法保证字段尚未定稿。@Lee您能再解释一下吗?您所说的“字段尚未最终确定”是什么意思?无法保证最终确定程序的执行顺序,因此在运行PackageDrawer
的最终确定程序时,其字段的最终确定程序可能已经执行。您的最终用户无法执行任何操作,因此应将其删除。您不需要最终用户,也不应使用它调用Dispose
,因为无法保证字段尚未最终用户。@Lee您能再解释一下吗?您所说的“字段尚未最终确定”是什么意思?无法保证最终确定程序的执行顺序,因此在运行PackageDrawer
的最终确定程序时,其字段的最终确定程序可能已经执行。您在Finalizer中无法执行任何操作,因此应该将其删除。Brush
是一种引用类型,而不是值类型。我所知道的.net中唯一实现IDisposable
的图形相关类型是类类型。实际上,我能想到的唯一实现IDispose
的struct
类型是实现继承该接口的其他接口(通常是IEnumerator
)的结果;实际上,它们都没有对IDisposable.Dispose做任何响应。
@supercat:事实上,我在回答中没有提到一次性结构
,我写了destroy(以某种方式)。Brush
是一种引用类型,不是值类型。据我所知,在.net中实现IDisposable
的唯一图形相关类型是类类型。实际上,我能想到的唯一实现IDispose
的struct
类型是实现继承该接口的其他接口(通常是IEnumerator
)的结果;它们中没有一个对IDisposable.Dispose做出响应