建议使用using
语句或调用Dispose()
方法来处理IDisposable
对象。在Visual Studio中,很难直观地了解某个对象是否是可释放的。
我的问题是:有没有办法在VS中识别IDisposable
对象?
建议使用using
语句或调用Dispose()
方法来处理IDisposable
对象。在Visual Studio中,很难直观地了解某个对象是否是可释放的。
我的问题是:有没有办法在VS中识别IDisposable
对象?
IDisposable
接口。但大多数情况下,这些类型提供了一个Close()
方法。 - JehofCA2213
是什么,而且我不应该去外部链接查找。 - TheLethalCoderIDisposable
这样的接口,您可以随时查看MSDN。FileStream
此类型实现了
IDisposable
接口。当您使用完该类型后,应直接或间接地处理它。要直接处理它,请在try/catch块中调用其Dispose方法。要间接处理它,请使用语言构造,如using(在C#中)或Using(在Visual Basic中)。有关详细信息,请参阅IDisposable界面主题中的“使用实现IDisposable的对象”一节。
or search for the Dispose
method. There you can see if this class or any parent class implements IDispable
. In this case it is inherited from Stream
which implements that interface which is mentioned at the class syntax and in the remarks section.
public abstract class Stream : MarshalByRefObject, IDisposable
要查看一个类实现了哪些接口,以及该类公开的所有字段、属性、方法等,可以进入该类的代码。例如:
Image image = Image.FromFile(path);
请确保您点击的是类,而不是实例,并按下 F12 键。这将带您到该类的元数据文件。例如:Image.cs
文件在类声明之前有以下内容:
public abstract class Image : MarshalByRefObject, ISerializable, ICloneable, IDisposable
.
。这应该会带出智能感知并且如果该项实现了接口,则您将能够在列表中看到Dispsose()
。myInstance.Dispose();
或 using (myInstance = new MyClass()) {}
,如果代码编译,则该类实现了接口,否则没有。Is Disposa&ble
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
-Command "&{$i=[Type]::GetType('System.IDisposable');[AppDomain]::CurrentDomain.GetAssemblies()|%{ $_.GetTypes()}|?{$_.FullName.EndsWith('.$(CurText)')}|%{New-Object PSObject -Property @{'Type'=$_;'IDisposable'=$i.IsAssignableFrom($_)}}|ft}"
这将读取您在编辑器中选择的任何字符串,搜索名称包含该字符串的.NET类型,并显示一个True/False,表示该字符串是否实现了IDisposable。
工具中的Powershell命令只是我能够演示这种可能性的最快方法,但它远非完美--它仅查找Powershell默认加载的程序集中的类型。如果您想扩展这个想法,您可以构建一个命令行.NET应用程序,加载您的项目并扫描您的项目加载的所有程序集。
例如,如果您在代码中突出显示单词Stream
,并运行您的外部工具(示例中为ALT+T,ALT+B),它将返回:
Type IDisposable ---- ----------- System.IO.Stream True
来分解Powershell命令:
&{ $i=[Type]::GetType('System.IDisposable'); # Get the IDisposable interface
[AppDomain]::CurrentDomain.GetAssemblies() ` # Get all loaded assemblies
| %{ $_.GetTypes() } ` # For each assembly, get all types
| ?{ $_.FullName.EndsWith('.$(CurText)') } ` # Filter types that are named $(CurText) - $(CurText) is a macro within VS External Tools
| %{ New-Object PSObject -Property @{ # For each type, return an object containing...
'Type' = $_; # ...the type name...
'IDisposable' = $i.IsAssignableFrom($_) # ...and whether the IDisposable interface is implemented
} } `
| ft } # Format all returned objects as a table
IDisposable
接口的方法,而无需第三方工具或手动遍历层次结构。加一! - Lance U. Matthews在Dispose()方法中使用using。
如果可以的话,最好使用using
结构。这是原因。使用这个MSDN的例子,下面是两个等价的代码块。这个用了using
:
using (Font font1 = new Font("Arial", 10.0f))
{
byte charset = font1.GdiCharSet;
}
这个没有使用
:
{
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}
using
结构存在的原因。using
/Dispose()
,而是如何识别哪些对象实现了 IDisposable
接口,因此应该使用 using
/Dispose()
进行处理。换句话说,你说“尽可能使用 using
结构”,而问题是“在 Visual Studio 中,我如何知道‘何时可以’?” - Lance U. Matthews在C#7中可以完成一些干净的事情
class Foo : IDisposable {
string _bar = "init";
void Fooy() { _bar = "fooy"; }
public void Dispose() {
_bar = null;
}
static void Main()
{
var v = new Foo();
Console.WriteLine(v._bar);
if(v is IDisposable id) using(id)
v.Fooy();
else
v.Fooy();
Console.WriteLine(v._bar ?? "null");;
}
}
Fooy
可能是一些虚拟或抽象函数。一些基类可能会实现 IDisposable
,而其他则不会。尝试运行上面的代码。控制台将根据是否实现了 IDisposable
打印不同的文本。
if
语句的两侧调用相同方法是“正确”的(尽管我不认为它很“干净”)。这个想法是无论 v
是否实现了 IDisposable
接口都调用 v.Fooy()
方法,然后如果它确实实现了 IDisposable
接口,则通过 using
对象释放 v
。也许将 using
翻译成 try
/finally
可以更清晰地表达:try { v.Fooy(); } finally { if (v is IDisposable id) id.Dispose(); }
,但这仍然看起来像是一个 IDE/文档问题的运行时解决方案。 - Lance U. Matthewsusing(id)
放进去。谢谢。 - 15ee8f99-57ff-4f92-890c-b56153
IDisposable
接口,并使用using
语句来实例化它们呢? - AlejandroDispose()
方法,而无需实现IDisposable
。 - krillgar