识别Visual Studio中的一次性对象?

时间:2017-04-26 13:07:30

标签: c# .net visual-studio intellisense idisposable

建议IDisposable个对象应该在using语句中或通过调用Dispose()方法处理。我发现在Visual Studio中找出对象是否是一次性的并不直观。

我的问题是:有没有办法识别VS中的IDisposable个对象?

8 个答案:

答案 0 :(得分:27)

如果您想在VS中以不同方式突出显示一次性物品,请查看此post。我个人更喜欢Resharper answer,因为我总是使用R#。

如果您只想弄清楚您的对象是否是某个界面的实例,您可以右键单击变量名称Navigate -> Object BrowserGo to Declaration,然后右键单击班级名称Go to Definition / Peek Definition

enter image description here

您可能希望Peek Definition因为它显示您需要内联的所有内容:

enter image description here

你可以随时检查对象有哪些方法,如果它有Dispose()方法,那么99.9%它是一次性对象。对于那些给方法名称不好的人,我会给这个0.01%。)。

答案 1 :(得分:11)

我很惊讶没有人提到过这个。如果您的edition of Visual Studio支持,我建议您为Build启用Code Analysis

完成后,只要确保至少CA2000(在丢失范围之前弃置对象),CA2213(一次性字段处置)和CA2202(不要多次处置对象)规则。这样,如果您没有正确处理一次性对象,编译器应大喊

(虽然注意到让编译器标记某些一次性对象的使用可能会变成更大的挑战,因为许多StackOverflow问题可以证明)

答案 2 :(得分:8)

您可以使用对象浏览器查看已实现接口的类继承层次结构

enter image description here

答案 3 :(得分:7)

为了完整起见,如果您没有询问如何在代码中检查它,但您只想知道如果类型实现了IDisposable这样的界面,您可以在哪里查看,您可以随时查看MSDN

例如FileStream

  • 在备注部分已经提到过:
  

此类型实现IDisposable接口。当你完成了   使用该类型,您应该直接或处理它   间接的影响。要直接处理类型,请调用其Dispose方法   在try / catch块中。要间接处理它,请使用一种语言   构造如使用(在C#中)或使用(在Visual Basic中)。更多   信息,请参阅“使用实现IDisposable的对象”   IDisposable接口主题中的部分。

  • 或搜索Dispose method。在那里,您可以看到此类或任何父类是否实现IDispable。在这种情况下,它继承自Stream,它实现了在类语法和备注部分中提到的接口。

    public abstract class Stream : MarshalByRefObject, IDisposable
    

如果您想知道如何在 Visual Studio 中查找界面的实现,这里已经有一个问题可以回答:

How do you find all implementations of an interface?

答案 4 :(得分:6)

查看类实现的接口以及所有公开的字段,属性,方法等的方法是在代码中转到该类。例如:

Image image = Image.FromFile(path);

确保单击该类,而不是实例,然后按F12。这将带您进入该类的元数据文件。例如:Image.cs文件具有以下类声明:

public abstract class Image : MarshalByRefObject, ISerializable, ICloneable, IDisposable

您也可以使用F12点击进入其他课程。请注意,这些类通常在Visual Studio中以浅蓝色显示:

Screenshot showing light blue colours.

您也可以通过右键单击该类并从下拉列表中选择“转到定义”来获取此元数据文件。

虽然不理想,但您也可以转到课程的实例并在最后添加.。这应该会显示智能感知,如果项目实现了界面,您将能够在列表中看到Dispsose()

您也可以只编写myInstance.Dispose();using (myInstance = new MyClass()) {},如果编译该类,则实现接口,否则不会。

答案 5 :(得分:4)

作为一个(愚蠢?)替代Resharper及其同类产品的替代方案,Visual Studio确实具有外部工具的概念(在工具菜单中),您可以(ab)使用它做类似的事情:

  • 标题: 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类型,并显示该字符串是否实现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

答案 6 :(得分:0)

"1";"16875170";"172";"50" "2";"11005137";"28";"39" "3";"16981017";"9347";"50" "4";"13771676";"13";"45" "5";"5865226";"963";"28" 尽可能使用either using or in Dispose() method构造。这就是原因。使用此MSDN示例,这里有两个等效的代码块。这个using

using

这一个没有using (Font font1 = new Font("Arial", 10.0f)) { byte charset = font1.GdiCharSet; }

using

第二个块的每个部分都有一个原因:花括号,try-finally,null检查和强制转换为IDisposable。不应该让人记住这一点。这就是{ Font font1 = new Font("Arial", 10.0f); try { byte charset = font1.GdiCharSet; } finally { if (font1 != null) ((IDisposable)font1).Dispose(); } } 构造存在的原因。

答案 7 :(得分:-2)

可以在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而其他基类则不会。尝试运行上面的代码。根据{{​​1}}是否已实施

,控制台将打印不同的文本