Functions & Methods
Defining reusable code
Introduction
In this lesson, you'll learn about functions & methods in C#. Coming from C, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In C, you're familiar with defining reusable code.
C# has its own approach to defining reusable code, which we'll explore step by step.
The C# Way
Let's see how C# handles this concept. Here's a typical example:
using System;
// C# methods must belong to a class
static class MathUtils {
public static int Add(int a, int b) => a + b;
public static void Greet(string name) =>
Console.WriteLine("Hello, " + name + "!");
// out parameters (like C pointer params)
public static void DivMod(int a, int b, out int q, out int r) {
q = a / b;
r = a % b;
}
// Func<T> replaces function pointers
public static int Apply(Func<int, int, int> op, int a, int b) =>
op(a, b);
}
MathUtils.DivMod(17, 5, out int q, out int rem);
Console.WriteLine(string.Format("{0} rem {1}", q, rem));
int result = MathUtils.Apply((a, b) => a + b, 3, 4);Comparing to C
Here's how you might have written similar code in C:
#include <stdio.h>
/* All functions are free-standing */
int add(int a, int b) {
return a + b;
}
void greet(const char *name) {
printf("Hello, %s!\n", name);
}
/* Multiple outputs via pointer params */
void divmod(int a, int b, int *q, int *r) {
*q = a / b;
*r = a % b;
}
/* Function pointer */
typedef int (*BinaryOp)(int, int);
int apply(BinaryOp op, int a, int b) {
return op(a, b);
}You may be used to different syntax or behavior.
C# methods must live inside a class; C functions are free-standing
You may be used to different syntax or behavior.
C# out parameters replace C's output pointer params
You may be used to different syntax or behavior.
C# Func<T> and lambda expressions replace C function pointers
You may be used to different syntax or behavior.
C# static class groups related functions like a C module
Step-by-Step Breakdown
1. Methods in Classes
C# has no free-standing functions — all code lives in classes. Use static classes to group utility functions like C source files.
int add(int a, int b) { return a + b; }static class MathUtils {
public static int Add(int a, int b) => a + b;
}2. out Parameters
C# out parameters replace C's output pointer params, with type safety and without needing to pass addresses.
void divmod(int a, int b, int *q, int *r) { *q = a/b; *r = a%b; }void DivMod(int a, int b, out int q, out int r) { q = a/b; r = a%b; }
// call: DivMod(17, 5, out int q, out int r);3. Func and Lambdas
C# Func<in, out> and lambda expressions replace C function pointer typedefs with type-safe, concise alternatives.
typedef int (*BinaryOp)(int, int);Func<int, int, int> op = (a, b) => a + b;
int result = op(3, 4);Common Mistakes
When coming from C, developers often make these mistakes:
- C# methods must live inside a class; C functions are free-standing
- C# out parameters replace C's output pointer params
- C# Func<T> and lambda expressions replace C function pointers
Key Takeaways
- All C# code lives in classes; use static for utility functions
- out parameters replace output pointer params
- Func<T> + lambdas replace function pointers
- Expression-bodied members (=>) for concise methods