Declaring and Calling Methods — The Building Blocks of Reuse

A method is a named block of code that performs a specific task and can be called from multiple places. Methods are the primary unit of code reuse in C# — instead of copying the same logic into every place that needs it, you write it once in a method and call it. Every ASP.NET Core controller action, every service layer operation, and every repository query is a method. Understanding method declaration, access modifiers, and naming conventions is the foundation of writing professional, maintainable C# code.

Declaring Methods

// Syntax: [accessModifier] [static] returnType MethodName([parameters])

// ── Void method — does work, returns nothing ───────────────────────────────
public void PrintGreeting(string name)
{
    Console.WriteLine($"Hello, {name}!");
}

// ── Method with return value ───────────────────────────────────────────────
public int Add(int a, int b)
{
    return a + b;
}

// ── Static method — called on the class, not an instance ──────────────────
public static double CircleArea(double radius)
{
    return Math.PI * radius * radius;
}

// ── Expression body (=>) — single-expression methods ──────────────────────
public int Multiply(int a, int b) => a * b;
public void SayHello() => Console.WriteLine("Hello!");
public static bool IsEven(int n) => n % 2 == 0;

// ── Calling methods ────────────────────────────────────────────────────────
var calc = new Calculator();
calc.PrintGreeting("Alice");          // instance method call
int sum    = calc.Add(10, 20);        // 30
double area = Calculator.CircleArea(5); // static method — called on type name
Note: Expression-bodied methods (=> syntax) are a concise C# 6+ feature for single-expression methods. They are not just syntactic sugar — they are idiomatic in modern .NET code. You will see them used extensively in ASP.NET Core for simple controller actions (public IActionResult GetById(int id) => Ok(_service.GetById(id));), property getters, and one-liner utility methods. Use them freely for simple cases; switch to a block body when you need multiple statements.
Tip: Follow .NET naming conventions for methods: PascalCase for method names (GetUser, CreatePost, not getUser or create_post). Use descriptive verb-noun names that describe what the method does: ValidateEmail(), SendNotification(), BuildConnectionString(). Avoid generic names like Process(), Handle(), or DoWork() — they reveal nothing about what the method actually does. Good names reduce the need for comments.
Warning: static methods cannot access instance fields or other instance methods — they have no this reference. A common mistake is declaring a helper method as static and then trying to call a non-static method from it: public static void Helper() { SomeInstanceMethod(); } — compile error. Reserve static for pure utility methods that do not depend on any object state, like format converters, math helpers, and extension methods. In ASP.NET Core, service layer methods are instance methods (the service is injected) not static.

Access Modifiers

Modifier Accessible From Common Use
public Any code in any assembly API controllers, service interfaces, DTOs
private Current class only Helper methods, backing fields
protected Current class + derived classes Base class methods for subclasses
internal Current assembly only Implementation classes not exposed to callers
protected internal Current assembly + derived classes Framework extension points
private protected Current class + derived classes in same assembly Rare — sealed subsystem hierarchies

XML Documentation Comments

/// <summary>
/// Calculates the discounted price of a product.
/// </summary>
/// <param name="originalPrice">The original price before discount.</param>
/// <param name="discountPercent">Discount as a percentage (0–100).</param>
/// <returns>The price after applying the discount.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown when discountPercent is not between 0 and 100.
/// </exception>
public decimal CalculateDiscountedPrice(decimal originalPrice, decimal discountPercent)
{
    if (discountPercent < 0 || discountPercent > 100)
        throw new ArgumentOutOfRangeException(nameof(discountPercent),
            "Discount must be between 0 and 100.");

    return originalPrice * (1 - discountPercent / 100);
}
// Swagger/OpenAPI reads these comments automatically for API documentation

Common Mistakes

Mistake 1 — Calling a static method on an instance (misleading)

❌ Wrong — compiles but implies the method depends on state:

var calc = new Calculator();
double area = calc.CircleArea(5);   // CircleArea is static — call on the type!

✅ Correct:

double area = Calculator.CircleArea(5);   // ✓ makes the static nature obvious

Mistake 2 — Method names in camelCase (Java/JavaScript habit)

❌ Wrong: public void getUser(int id), public bool validateEmail(string email)

✅ Correct: public void GetUser(int id), public bool ValidateEmail(string email) — always PascalCase in C#.

🧠 Test Yourself

When should you use an expression-bodied method (=>) versus a block body ({ })?