diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs
index ba47e47b..03b97157 100644
--- a/src/Generator/Generators/CSharp/CSharpSources.cs
+++ b/src/Generator/Generators/CSharp/CSharpSources.cs
@@ -113,42 +113,36 @@ namespace CppSharp.Generators.CSharp
                                   group spec by module.OutputNamespace into @group
                                   select @group)
             {
-                PushBlock(BlockKind.Namespace);
-                if (!string.IsNullOrEmpty(group.Key))
-                {
-                    WriteLine($"namespace {group.Key}");
-                    WriteOpenBraceAndIndent();
-                }
-
-                foreach (var template in from s in @group
-                                         group s by s.TemplatedDecl.TemplatedClass into template
-                                         select template)
+                using (!string.IsNullOrEmpty(group.Key) 
+                    ? PushWriteBlock(BlockKind.Namespace, $"namespace {group.Key}", NewLineKind.BeforeNextBlock) 
+                    : default)
                 {
-                    var declContext = template.Key.Namespace;
-                    var declarationContexts = new Stack<DeclarationContext>();
-                    while (!(declContext is TranslationUnit))
+                    foreach (var template in from s in @group
+                                             group s by s.TemplatedDecl.TemplatedClass into template
+                                             select template)
                     {
-                        if (!(declContext is Namespace @namespace) || !@namespace.IsInline)
-                            declarationContexts.Push(declContext);
-                        declContext = declContext.Namespace;
-                    }
+                        var declContext = template.Key.Namespace;
+                        var declarationContexts = new Stack<DeclarationContext>();
+                        while (!(declContext is TranslationUnit))
+                        {
+                            if (!(declContext is Namespace @namespace) || !@namespace.IsInline)
+                                declarationContexts.Push(declContext);
+                            declContext = declContext.Namespace;
+                        }
 
-                    foreach (var declarationContext in declarationContexts)
-                    {
-                        WriteLine($"namespace {declarationContext.Name}");
-                        WriteOpenBraceAndIndent();
-                    }
+                        foreach (var declarationContext in declarationContexts)
+                        {
+                            WriteLine($"namespace {declarationContext.Name}");
+                            WriteOpenBraceAndIndent();
+                        }
 
-                    GenerateClassTemplateSpecializationsInternals(
-                        template.Key, template.ToList());
+                        GenerateClassTemplateSpecializationsInternals(
+                            template.Key, template.ToList());
 
-                    foreach (var declarationContext in declarationContexts)
-                        UnindentAndWriteCloseBrace();
+                        foreach (var declarationContext in declarationContexts)
+                            UnindentAndWriteCloseBrace();
+                    }
                 }
-
-                if (!string.IsNullOrEmpty(group.Key))
-                    UnindentAndWriteCloseBrace();
-                PopBlock(NewLineKind.BeforeNextBlock);
             }
 
             if (Options.GenerationOutputMode == GenerationOutputMode.FilePerUnit)
@@ -194,22 +188,11 @@ namespace CppSharp.Generators.CSharp
             var shouldGenerateNamespace = !@namespace.IsInline && !isTranslationUnit &&
                 context.Declarations.Any(d => d.IsGenerated || (d is Class && !d.IsIncomplete));
 
-            if (shouldGenerateNamespace)
-            {
-                PushBlock(BlockKind.Namespace);
-                WriteLine("namespace {0}", context.Name);
-                WriteOpenBraceAndIndent();
-            }
-
-            var ret = base.VisitNamespace(@namespace);
-
-            if (shouldGenerateNamespace)
-            {
-                UnindentAndWriteCloseBrace();
-                PopBlock(NewLineKind.BeforeNextBlock);
-            }
+            using var _ = shouldGenerateNamespace 
+                ? PushWriteBlock(BlockKind.Namespace, $"namespace {context.Name}", NewLineKind.BeforeNextBlock) 
+                : default;
 
-            return ret;
+            return base.VisitNamespace(@namespace);
         }
 
         public override bool VisitDeclContext(DeclarationContext context)
@@ -316,14 +299,13 @@ namespace CppSharp.Generators.CSharp
         private void GenerateClassTemplateSpecializationsInternals(Class template,
             IList<ClassTemplateSpecialization> specializations)
         {
-            PushBlock(BlockKind.Namespace);
-            var generated = GetGeneratedClasses(template, specializations);
-            WriteLine("namespace {0}{1}",
+            var namespaceName = string.Format("namespace {0}{1}",
                 template.OriginalNamespace is Class &&
                 !template.OriginalNamespace.IsDependent ?
                     template.OriginalNamespace.Name + '_' : string.Empty,
                 template.Name);
-            WriteOpenBraceAndIndent();
+            using var _ = PushWriteBlock(BlockKind.Namespace, namespaceName, NewLineKind.BeforeNextBlock);
+            var generated = GetGeneratedClasses(template, specializations);
 
             foreach (var nestedTemplate in template.Classes.Where(
                 c => c.IsDependent && !c.Ignore && c.Specializations.Any(s => !s.Ignore)))
@@ -342,22 +324,19 @@ namespace CppSharp.Generators.CSharp
                 if (nested != null)
                     GenerateNestedInternals(group.Key, GetGeneratedClasses(nested, group));
             }
-
-            UnindentAndWriteCloseBrace();
-            PopBlock(NewLineKind.BeforeNextBlock);
         }
 
         private void GenerateNestedInternals(string name, IEnumerable<Class> nestedClasses)
         {
-            WriteLine($"namespace {name}");
-            WriteOpenBraceAndIndent();
-            foreach (var nestedClass in nestedClasses)
+            using (WriteBlock($"namespace {name}"))
             {
-                GenerateClassInternals(nestedClass);
-                foreach (var nestedInNested in nestedClass.Classes)
-                    GenerateNestedInternals(nestedInNested.Name, new[] { nestedInNested });
+                foreach (var nestedClass in nestedClasses)
+                {
+                    GenerateClassInternals(nestedClass);
+                    foreach (var nestedInNested in nestedClass.Classes)
+                        GenerateNestedInternals(nestedInNested.Name, new[] { nestedInNested });
+                }
             }
-            UnindentAndWriteCloseBrace();
             NewLine();
         }
 
@@ -2256,14 +2235,8 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat
             if (!Options.GenerateFinalizerFor(@class))
                 return;
 
-            PushBlock(BlockKind.Finalizer);
-
-            WriteLine("~{0}()", @class.Name);
-            WriteOpenBraceAndIndent();
-            WriteLine($"Dispose(false, callNativeDtor : { Helpers.OwnsNativeInstanceIdentifier} );");
-            UnindentAndWriteCloseBrace();
-
-            PopBlock(NewLineKind.BeforeNextBlock);
+            using (PushWriteBlock(BlockKind.Finalizer, $"~{@class.Name}()", NewLineKind.BeforeNextBlock))
+                WriteLine($"Dispose(false, callNativeDtor : { Helpers.OwnsNativeInstanceIdentifier} );");
         }
 
         private void GenerateDisposeMethods(Class @class)
@@ -2273,16 +2246,12 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat
             // Generate the IDispose Dispose() method.
             if (!hasBaseClass)
             {
-                PushBlock(BlockKind.Method);
-                WriteLine("public void Dispose()");
-                WriteOpenBraceAndIndent();
-
-                WriteLine($"Dispose(disposing: true, callNativeDtor : { Helpers.OwnsNativeInstanceIdentifier} );");
-                if (Options.GenerateFinalizerFor(@class))
-                    WriteLine("GC.SuppressFinalize(this);");
-
-                UnindentAndWriteCloseBrace();
-                PopBlock(NewLineKind.BeforeNextBlock);
+                using (PushWriteBlock(BlockKind.Method, "public void Dispose()", NewLineKind.BeforeNextBlock))
+                {
+                    WriteLine($"Dispose(disposing: true, callNativeDtor : { Helpers.OwnsNativeInstanceIdentifier} );");
+                    if (Options.GenerateFinalizerFor(@class))
+                        WriteLine("GC.SuppressFinalize(this);");
+                }
             }
 
             // Declare partial method that the partial class can implement to participate
@@ -2292,13 +2261,8 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat
             PopBlock(NewLineKind.BeforeNextBlock);
 
             // Generate Dispose(bool, bool) method
-            PushBlock(BlockKind.Method);
-            Write("internal protected ");
-            if (!@class.IsValueType)
-                Write(hasBaseClass ? "override " : "virtual ");
-
-            WriteLine("void Dispose(bool disposing, bool callNativeDtor )");
-            WriteOpenBraceAndIndent();
+            var ext = !@class.IsValueType ? (hasBaseClass ? "override " : "virtual ") : string.Empty;
+            using var _ = PushWriteBlock(BlockKind.Method, $"internal protected {ext}void Dispose(bool disposing, bool callNativeDtor )", NewLineKind.BeforeNextBlock);
 
             if (@class.IsRefType)
             {
@@ -2391,8 +2355,6 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat
             WriteLineIndent("Marshal.FreeHGlobal({0});", Helpers.InstanceIdentifier);
 
             WriteLine("{0} = IntPtr.Zero;", Helpers.InstanceIdentifier);
-            UnindentAndWriteCloseBrace();
-            PopBlock(NewLineKind.BeforeNextBlock);
         }
 
         private bool GenerateDestructorCall(Method dtor)
diff --git a/src/Generator/Utils/BlockGenerator.cs b/src/Generator/Utils/BlockGenerator.cs
index f0bcfb67..1dff9927 100644
--- a/src/Generator/Utils/BlockGenerator.cs
+++ b/src/Generator/Utils/BlockGenerator.cs
@@ -298,6 +298,42 @@ namespace CppSharp
             return FindBlocks(kind).SingleOrDefault();
         }
 
+        internal PushedBlock PushWriteBlock(BlockKind kind, string msg, NewLineKind next)
+        {
+            PushBlock(kind);
+            WriteLine(msg);
+            WriteOpenBraceAndIndent();
+            return new PushedBlock(this, next);
+        }
+
+        internal TextBlock WriteBlock(string msg)
+        {
+            WriteLine(msg);
+            WriteOpenBraceAndIndent();
+            return new TextBlock(this);
+        }
+
+        internal ref struct PushedBlock
+        {
+            private readonly BlockGenerator generator;
+            private readonly NewLineKind next;
+
+            public PushedBlock(BlockGenerator generator, NewLineKind next) 
+            {
+                this.generator = generator;
+                this.next = next;
+            }
+
+            public void Dispose()
+            {
+                if (generator == null)
+                    return;
+
+                generator.UnindentAndWriteCloseBrace();
+                generator.PopBlock(next);
+            }
+        }
+
         #endregion
 
         #region ITextGenerator implementation