Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. IDisposable and CA2000 warning during Vs2010 Code Analysis.

IDisposable and CA2000 warning during Vs2010 Code Analysis.

Scheduled Pinned Locked Moved C#
helpregexquestion
9 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    gumi_r msn com
    wrote on last edited by
    #1

    Hi all, I need some advice here, I hope somebody can help me. I have the following class structure (simplified):

    public class Bar: IDisposable {...}

    public abstract class FooBase: IDisposable
    {
    Bar bar;
    bool disposed;

    internal FooBase(Bar bar)
    {
    this.bar=bar;
    }

    public void Dispose()
    {
    if (!this.disposed)
    {
    this.bar.Dispose(true);
    GC.SupressFinalize(this);
    this.disposed = true;
    }
    }

    protected void Dipose(bool disposing)
    {
    if (disposing)
    {
    this.bar.Dispose();
    }
    }
    }

    public FooA: Foo {...}
    public FooB: Foo {...}

    public static class FooProvider
    {
    public static FooA GetFooA()
    {
    Bar bar = new Bar();
    ...
    return new FooA(bar);
    }

    public static FooB GetFooB()
    {
    Bar bar = new Bar();
    ...
    return new FooB(bar);
    }

    ...
    }

    When I run Code Analysis on this, I get Warnings CA2000 on all 'CreateFooX()' methods of the FooProvider class. This warning gives the following message: "Microsoft. Reliability: In method 'FooProvider.GetFooX()', call System.IDisposable.Dispose on object 'bar' before all references to it are out of scope." Microsoft recommends to never supress this warning but I'm not really sure its warning about a real problem in the code. True that 'bar' is not disposed before going out of scope in whatever 'CreateFooX()' method we consider but a reference to it lives on in the 'FooX' object which eventually will get disposed and will in turn take care of disposing 'bar'. Am I understanding something wrong about how the Dispose pattern should work and I have some fundamental flaw in my code or should I just supress this warning? Thanks for any advice.

    S 1 Reply Last reply
    0
    • G gumi_r msn com

      Hi all, I need some advice here, I hope somebody can help me. I have the following class structure (simplified):

      public class Bar: IDisposable {...}

      public abstract class FooBase: IDisposable
      {
      Bar bar;
      bool disposed;

      internal FooBase(Bar bar)
      {
      this.bar=bar;
      }

      public void Dispose()
      {
      if (!this.disposed)
      {
      this.bar.Dispose(true);
      GC.SupressFinalize(this);
      this.disposed = true;
      }
      }

      protected void Dipose(bool disposing)
      {
      if (disposing)
      {
      this.bar.Dispose();
      }
      }
      }

      public FooA: Foo {...}
      public FooB: Foo {...}

      public static class FooProvider
      {
      public static FooA GetFooA()
      {
      Bar bar = new Bar();
      ...
      return new FooA(bar);
      }

      public static FooB GetFooB()
      {
      Bar bar = new Bar();
      ...
      return new FooB(bar);
      }

      ...
      }

      When I run Code Analysis on this, I get Warnings CA2000 on all 'CreateFooX()' methods of the FooProvider class. This warning gives the following message: "Microsoft. Reliability: In method 'FooProvider.GetFooX()', call System.IDisposable.Dispose on object 'bar' before all references to it are out of scope." Microsoft recommends to never supress this warning but I'm not really sure its warning about a real problem in the code. True that 'bar' is not disposed before going out of scope in whatever 'CreateFooX()' method we consider but a reference to it lives on in the 'FooX' object which eventually will get disposed and will in turn take care of disposing 'bar'. Am I understanding something wrong about how the Dispose pattern should work and I have some fundamental flaw in my code or should I just supress this warning? Thanks for any advice.

      S Offline
      S Offline
      Subin Mavunkal
      wrote on last edited by
      #2

      you can fix this warning by applying 'using'.Do like this. public static FooA GetFooA() { using(var bar = new Bar()) { ... return new FooA(bar); } } public static FooB GetFooB() { using(var bar = new Bar()) { ... return new FooB(bar); } }

      P G 2 Replies Last reply
      0
      • S Subin Mavunkal

        you can fix this warning by applying 'using'.Do like this. public static FooA GetFooA() { using(var bar = new Bar()) { ... return new FooA(bar); } } public static FooB GetFooB() { using(var bar = new Bar()) { ... return new FooB(bar); } }

        P Offline
        P Offline
        Pete OHanlon
        wrote on last edited by
        #3

        OK. Now have a think about what effect calling Dispose on an item that you've just allocated via a constructor will be. Explain to the OP what happens when you attempt to access bar in FooB or FooA.

        Forgive your enemies - it messes with their heads

        My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility

        1 Reply Last reply
        0
        • S Subin Mavunkal

          you can fix this warning by applying 'using'.Do like this. public static FooA GetFooA() { using(var bar = new Bar()) { ... return new FooA(bar); } } public static FooB GetFooB() { using(var bar = new Bar()) { ... return new FooB(bar); } }

          G Offline
          G Offline
          gumi_r msn com
          wrote on last edited by
          #4

          Thanks for the reply but that is not a valid solution. If I do that, GetFooX() will be returning an invalid FooX object(disposed bar).

          S 1 Reply Last reply
          0
          • G gumi_r msn com

            Thanks for the reply but that is not a valid solution. If I do that, GetFooX() will be returning an invalid FooX object(disposed bar).

            S Offline
            S Offline
            Subin Mavunkal
            wrote on last edited by
            #5

            No , Just check the scope of "using". It will track the instance 'bar'

            P G 2 Replies Last reply
            0
            • S Subin Mavunkal

              No , Just check the scope of "using". It will track the instance 'bar'

              P Offline
              P Offline
              Pete OHanlon
              wrote on last edited by
              #6

              This is why I said you should explain the effect of the using statement further, I knew it would cause you confusion.

              Forgive your enemies - it messes with their heads

              My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility

              1 Reply Last reply
              0
              • S Subin Mavunkal

                No , Just check the scope of "using". It will track the instance 'bar'

                G Offline
                G Offline
                gumi_r msn com
                wrote on last edited by
                #7

                I'm sorry but that is wrong. A use statement is just syntactic sugar for a try finally block. What you are proposing translates to:

                Bar bar = null;
                try
                {
                bar = new Bar();
                ...
                return new FooX(bar);
                }
                finally
                {
                if (bar != null)
                {
                bar.Dispose();
                }
                }

                When the method gets to the return statement, it will execute the finally clause before exiting the method's scope returning a FooX object with a disposed bar. If you are not convinced execute the following code:

                using System;
                using System.Collections.Generic;
                using System.Linq;
                using System.Text;

                namespace Tests
                {
                class Program
                {
                static void Main(string[] args)
                {
                Console.WriteLine("Creating FooA 'fooA' from GetFooAWithUsingStatement.");
                FooA fooA=FooProvider.GetFooAWithUsingStatement();
                Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                Console.WriteLine("Disposing 'fooA'");
                fooA.Dispose();
                Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                Console.WriteLine();
                Console.WriteLine("Creating FooA 'fooA' from GetFooAWithoutUsingStatement.");
                fooA = FooProvider.GetFooWithoutUsingStatement();
                Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                Console.WriteLine("Disposing 'fooA'");
                fooA.Dispose();
                Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                Console.Write("Press a key to exit.");
                Console.ReadKey();
                }
                }

                class Bar : IDisposable
                {
                    bool disposed;
                
                    public void Dispose()
                    {
                        this.disposed = true;
                    }
                
                    public bool IsDisposed { get { return this.disposed; } }
                }
                
                static class FooProvider
                {
                    public static FooA GetFooAWithUsingStatement()
                    {
                        using (Bar bar = new Bar())
                        {
                            return new FooA(bar);
                        }
                    }
                
                    public static FooA GetFooWithoutUsingStatement()
                    {
                        Bar bar = new Bar();
                        return new FooA(bar);
                    }
                }
                
                class FooBase : IDisposable
                {
                    bool disposed;
                    Bar bar;
                
                    internal FooBase(Bar bar)
                    {
                        this.bar = bar;
                    }
                
                    public void Dispose()
                
                S D 2 Replies Last reply
                0
                • G gumi_r msn com

                  I'm sorry but that is wrong. A use statement is just syntactic sugar for a try finally block. What you are proposing translates to:

                  Bar bar = null;
                  try
                  {
                  bar = new Bar();
                  ...
                  return new FooX(bar);
                  }
                  finally
                  {
                  if (bar != null)
                  {
                  bar.Dispose();
                  }
                  }

                  When the method gets to the return statement, it will execute the finally clause before exiting the method's scope returning a FooX object with a disposed bar. If you are not convinced execute the following code:

                  using System;
                  using System.Collections.Generic;
                  using System.Linq;
                  using System.Text;

                  namespace Tests
                  {
                  class Program
                  {
                  static void Main(string[] args)
                  {
                  Console.WriteLine("Creating FooA 'fooA' from GetFooAWithUsingStatement.");
                  FooA fooA=FooProvider.GetFooAWithUsingStatement();
                  Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                  Console.WriteLine("Disposing 'fooA'");
                  fooA.Dispose();
                  Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                  Console.WriteLine();
                  Console.WriteLine("Creating FooA 'fooA' from GetFooAWithoutUsingStatement.");
                  fooA = FooProvider.GetFooWithoutUsingStatement();
                  Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                  Console.WriteLine("Disposing 'fooA'");
                  fooA.Dispose();
                  Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                  Console.Write("Press a key to exit.");
                  Console.ReadKey();
                  }
                  }

                  class Bar : IDisposable
                  {
                      bool disposed;
                  
                      public void Dispose()
                      {
                          this.disposed = true;
                      }
                  
                      public bool IsDisposed { get { return this.disposed; } }
                  }
                  
                  static class FooProvider
                  {
                      public static FooA GetFooAWithUsingStatement()
                      {
                          using (Bar bar = new Bar())
                          {
                              return new FooA(bar);
                          }
                      }
                  
                      public static FooA GetFooWithoutUsingStatement()
                      {
                          Bar bar = new Bar();
                          return new FooA(bar);
                      }
                  }
                  
                  class FooBase : IDisposable
                  {
                      bool disposed;
                      Bar bar;
                  
                      internal FooBase(Bar bar)
                      {
                          this.bar = bar;
                      }
                  
                      public void Dispose()
                  
                  S Offline
                  S Offline
                  Subin Mavunkal
                  wrote on last edited by
                  #8

                  Then it is better to suppress the warning.

                  1 Reply Last reply
                  0
                  • G gumi_r msn com

                    I'm sorry but that is wrong. A use statement is just syntactic sugar for a try finally block. What you are proposing translates to:

                    Bar bar = null;
                    try
                    {
                    bar = new Bar();
                    ...
                    return new FooX(bar);
                    }
                    finally
                    {
                    if (bar != null)
                    {
                    bar.Dispose();
                    }
                    }

                    When the method gets to the return statement, it will execute the finally clause before exiting the method's scope returning a FooX object with a disposed bar. If you are not convinced execute the following code:

                    using System;
                    using System.Collections.Generic;
                    using System.Linq;
                    using System.Text;

                    namespace Tests
                    {
                    class Program
                    {
                    static void Main(string[] args)
                    {
                    Console.WriteLine("Creating FooA 'fooA' from GetFooAWithUsingStatement.");
                    FooA fooA=FooProvider.GetFooAWithUsingStatement();
                    Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                    Console.WriteLine("Disposing 'fooA'");
                    fooA.Dispose();
                    Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                    Console.WriteLine();
                    Console.WriteLine("Creating FooA 'fooA' from GetFooAWithoutUsingStatement.");
                    fooA = FooProvider.GetFooWithoutUsingStatement();
                    Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                    Console.WriteLine("Disposing 'fooA'");
                    fooA.Dispose();
                    Console.WriteLine("'fooA' internal bar is disposed: {0}", fooA.InternalBarIsDisposed);
                    Console.Write("Press a key to exit.");
                    Console.ReadKey();
                    }
                    }

                    class Bar : IDisposable
                    {
                        bool disposed;
                    
                        public void Dispose()
                        {
                            this.disposed = true;
                        }
                    
                        public bool IsDisposed { get { return this.disposed; } }
                    }
                    
                    static class FooProvider
                    {
                        public static FooA GetFooAWithUsingStatement()
                        {
                            using (Bar bar = new Bar())
                            {
                                return new FooA(bar);
                            }
                        }
                    
                        public static FooA GetFooWithoutUsingStatement()
                        {
                            Bar bar = new Bar();
                            return new FooA(bar);
                        }
                    }
                    
                    class FooBase : IDisposable
                    {
                        bool disposed;
                        Bar bar;
                    
                        internal FooBase(Bar bar)
                        {
                            this.bar = bar;
                        }
                    
                        public void Dispose()
                    
                    D Offline
                    D Offline
                    DaveyM69
                    wrote on last edited by
                    #9

                    IMO, the warning is invalid in this situation. If the method was simply returning Bar then you would not get the warning, so it's not understanding that returned Foo requires Bar so should not be disposed.

                    Dave
                    Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
                    BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups