C#
block equivalent
programming language
code structure
software development

With block equivalent in C?

Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms

Introduction

VB.NET has a With block that lets you call multiple members on the same object without repeating the variable name. C# has no direct equivalent. However, C# offers several constructs that achieve similar conciseness: object initializers, local variables with short names, extension methods, and the using alias. Each approach trades off readability, safety, and applicability differently.

The VB.NET With Block

vb
1With myButton
2    .Text = "Click Me"
3    .Width = 200
4    .Height = 50
5    .Enabled = True
6End With

Inside the With block, the dot prefix refers to myButton. Every member access is implicitly scoped to that object.

C# Alternative 1: Object Initializer

When creating a new object, C# object initializers provide the closest syntax:

csharp
1var button = new Button
2{
3    Text = "Click Me",
4    Width = 200,
5    Height = 50,
6    Enabled = true
7};

This only works at construction time. You cannot use it to configure an existing object after creation.

C# Alternative 2: Short Local Variable

The simplest workaround for an existing object — assign it to a short-named variable:

csharp
1var b = existingButton;
2b.Text = "Click Me";
3b.Width = 200;
4b.Height = 50;
5b.Enabled = true;

Since b is a reference (for reference types), changes apply to the original object. This is the most common pattern in C# codebases.

C# Alternative 3: Extension Method for Fluent Configuration

Create a generic extension method that accepts an Action<T>:

csharp
1public static class ObjectExtensions
2{
3    public static T Apply<T>(this T obj, Action<T> action)
4    {
5        action(obj);
6        return obj;
7    }
8}
9
10// Usage
11existingButton.Apply(b =>
12{
13    b.Text = "Click Me";
14    b.Width = 200;
15    b.Height = 50;
16    b.Enabled = true;
17});

The Apply method passes the object into the lambda, simulating a With block. Returning obj enables chaining if needed.

C# Alternative 4: Fluent Builder / Method Chaining

Many C# libraries use fluent APIs that return this from each method:

csharp
1new HostBuilder()
2    .ConfigureServices(services => services.AddSingleton<IMyService, MyService>())
3    .ConfigureLogging(logging => logging.AddConsole())
4    .Build();

You can design your own classes to support this pattern:

csharp
1public class ButtonBuilder
2{
3    private readonly Button _button = new();
4
5    public ButtonBuilder WithText(string text) { _button.Text = text; return this; }
6    public ButtonBuilder WithSize(int w, int h) { _button.Width = w; _button.Height = h; return this; }
7    public Button Build() => _button;
8}
9
10var button = new ButtonBuilder()
11    .WithText("Click Me")
12    .WithSize(200, 50)
13    .Build();

C# Alternative 5: using static for Scoped Methods

When calling many static methods from the same class, using static reduces repetition:

csharp
1using static System.Math;
2
3double result = Sqrt(Pow(x, 2) + Pow(y, 2));
4// Without 'using static': Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2))

This does not apply to instance members but eliminates the class prefix for static calls.

C# 12 Primary Constructors and init Properties

Modern C# provides init properties and required members that reduce boilerplate at construction:

csharp
1public class Button
2{
3    public required string Text { get; init; }
4    public int Width { get; init; }
5    public int Height { get; init; }
6}
7
8var button = new Button
9{
10    Text = "Click Me",
11    Width = 200,
12    Height = 50
13};
14// button.Text = "Changed"; // ERROR: init-only property

This enforces immutability after construction — a different goal from With, but it addresses the same verbosity problem.

Comparison Table

ApproachWorks on Existing ObjectsType-SafeRequires Extra Code
Object initializerNo (creation only)YesNo
Short local variableYesYesNo
Apply extensionYesYesOne-time extension method
Fluent builderDepends on designYesPer-class builder
using staticStatic members onlyYesNo

Common Pitfalls

  • Using object initializers on existing objects: Object initializers only work in new expressions. You cannot write existingButton { Text = "X" } — use a local variable or lambda instead.
  • Value type gotcha with short variable alias: For structs, var b = existingStruct copies the value. Changes to b do not affect the original. Use ref var b = ref existingStruct (C# 7+) if you need a reference.
  • Overusing the Apply pattern: Wrapping every property assignment in a lambda adds a closure allocation and reduces debuggability. Use it sparingly for configuration-heavy sections, not for one or two property sets.
  • Fluent builders hiding mutation: If a builder mutates the object in place (instead of creating copies), calling .Build() twice returns the same modified object. Document whether the builder is reusable or single-use.
  • Assuming C# will add a with keyword for classes: C# records have with expressions, but they create a copy — they do not mutate the original. var b2 = b1 with { Text = "New" } gives a new record instance, not a With block.

Summary

  • C# has no direct With block equivalent from VB.NET
  • Object initializers handle the creation case cleanly
  • For existing objects, assign to a short local variable — simplest and most idiomatic
  • The Apply<T> extension method simulates a With block using a lambda
  • Fluent APIs and method chaining provide a similar developer experience for well-designed classes
  • C# records support with expressions, but they create copies rather than mutating in place

Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms