Introduction to Methods
Methods in C# are basically the fundamental building blocks of the language and allows the developers to encapsulate and re use code into reusable and manage able units. It allows us to perform operations, manipulate data and on it implement functionality in a structured way. In any C# application, understanding methods is the basic need for writing efficient and maintainable code.
Methods decrease code duplication, makes the codebase easier to manage and makes it easier to read. Developers can break the big problem into smaller, more manageable parts, each of which finishes a particular task. The approach breaks down into modular pieces so that developers can collaborate more easily and it also reduces debugging and testing process.
In this guide, I will take you through the meat of C# methods, from declaring these methods in C#, to invoking them, their parameters, what does return values mean, as well as more advanced features such as overloading, recursion and async methods. From a beginner to an experience developer, this detailed guide will help you to understand such methods in C#.
What is a Method?
It is a code block existing procedure in C# which has a series of statement to perform a specific action. It’s a function that takes in input parameters and returns a value, and defines what a class or an object will do. Code reuse and organization is encouraged through methods allowing developers to call the same code from several different places within the program.
In other programming languages, methods are thought of as functions. You can do computation, manipulate object state, talking with other methods or classes. The methods we have can help us Developers create modular code to make it easier to maintain and scale Applications.
Classes or structs define methods that are either instance methods (that require an object constructed from their class) or static methods (that belong to their class). Any C# developer needs to understand how to use methods effectively and understand how to declare methods.
Declaring a Method
Syntax and Explanation for Each Element
The general syntax for declaring a method in C# is:
[access_modifier] [return_type] MethodName([parameters])
{
// Method body
}
- Access Modifier: It specifies what is visible for the method. Public, private, protected, internal are common access modifiers and protected internal also exist.
- Return Type: It tells the type of value the method will return. If the return type of the method is void, which means that it doesn’t return any value, then this is called in Java.
- MethodName: A name of the method, and it should describe the purpose of the method.
- Parameters: Parameters that method accepts, and a type and a name for each. A method can have zero or more parameters and parameters are optional.
- Method Body: containing the code that defines what the method does, and enclosed in curly braces, {}
Access Rights
Access modifiers control how the methods can be accessed from other classes or assemblies:
- public: It’s got access from other classes.
- private: However the method is only available within the class it is declared in.
- protected: Is available within the class and in derived class instances.
- internal: Not accessible within another assembly but accessible within the same assembly.
- protected internal: Available within the same assembly, and available from derived classes.
The right access modifier is a must when trying to encapsulate and limit the access to class members.
public class Calculator
{
// Public method accessible from anywhere
public int Add(int a, int b)
{
return a + b;
}
// Private method accessible only within this class
private void DisplayResult(int result)
{
Console.WriteLine("The result is: " + result);
}
}
In this case, Add is public and you can call this method from other classes. As the DisplayResult method is private, it only can be used within calculator class.
Method Invocation
Calling a method is known as invoking a method. C# is a class based language and in C# methods may be instance methods or static methods, and they are called in slightly different way.
Instance Method Invocation
Class methods don’t require creation of an object to be able to run. It’s the class instance variables, they can perform on it and they can get both static and non static member.
To invoke an instance method
Use the class variable. When you want to use the method on the object in the dot . operator.
public class Greeter
{
public void SayHello(string name)
{
Console.WriteLine("Hello, " + name + "!");
}
}
// Usage
Greeter greeter = new Greeter();
greeter.SayHello("Alice");
SayHello is the instance method of the Greeter class, in this example. We create an object greeter to call it’s SayHello method.
Static Method Invocation
Static methods go along with the class, and not the particular object. They can neither be created without an instance of the class being created nor use any class member except for static members.
To invoke a static method
The practice is to use the class name with the dot . operator and followed by the method name.
public class MathUtility
{
public static int Square(int number)
{
return number * number;
}
}
// Usage
int result = MathUtility.Square(5);
Console.WriteLine(result); // Output: 25
Square is a static method and here we are calling it with the class name MathUtility.
Default and Optional Parameters
Using optional parameters with default value in methods were supported by c# So when calling this method, you are able to include (or not) values for these parameters, as the default values will be included.
In the method declaration, optional parameters are defined by default value.
public class Logger
{
public void LogMessage(string message, string severity = "Info")
{
Console.WriteLine($"[{severity}] {message}");
}
}
// Usage
Logger logger = new Logger();
logger.LogMessage("Application started."); // Uses default severity "Info"
logger.LogMessage("An error occurred.", "Error"); // Specifies severity "Error"
The severity of the LogMessage method has a default value of “Info” as is indicated in this example. Default severity is “Info” if the caller doesn’t provide the severity.
Passing Arguments to Methods
Passing arguments to a method are called arguments passing by value or arguments passing by reference. The difference is important to know so you know how to manipulate data within methods.
Passing by Value
Arguments in C# are passed by value, by default. That means we create a copy of the variable and updating inside the method doesn’t affect the actual variable.
public void Increment(int number)
{
number++;
Console.WriteLine("Inside method: " + number);
}
// Usage
int value = 5;
Increment(value);
Console.WriteLine("After method call: " + value);
Inside method: 6
After method call: 5
When calling this method, number is a copy and so the value remains the same.
Passing by Reference
When you serve a method passing by reference, you can modify the original variable. And in C#, it’s done using the ref or out keywords.
public void Increment(ref int number)
{
number++;
Console.WriteLine("Inside method: " + number);
}
// Usage
int value = 5;
Increment(ref value);
Console.WriteLine("After method call: " + value);
Inside method: 6
After method call: 6
Number inside Increment has been ref’d, so changes to number inside the Increment will affect the original value.
Parameter Collections
In C# you can pass a variable number of arguments to a method as an array using the params keyword. When we don’t know the exact number of parameters a function takes, this helps.
public void PrintNumbers(params int[] numbers)
{
foreach (int number in numbers)
{
Console.WriteLine(number);
}
}
// Usage
PrintNumbers(1, 2, 3, 4, 5);
For this example, PrintNumbers takes any number of integer arguments and processes them as an array inside of the method.
Return Values
The return keyword followed by a value, which fits the method’s return type, is the way to return values with methods. A method that is not voided must return a value.
public double CalculateArea(double radius)
{
return Math.PI * radius * radius;
}
// Usage
double area = CalculateArea(5);
Console.WriteLine("Area: " + area);
The CalculateArea method takes in the radius and calculate and returns the area of a circle.
Inherited and Overridden Methods
Inheritance is the act of inheritance from a base class to a class. Classes in the derived class can entirely replace the methods offered from the base class with specialized behavior.
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("The animal makes a sound.");
}
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("The dog barks.");
}
}
// Usage
Animal myAnimal = new Animal();
myAnimal.Speak(); // Output: The animal makes a sound.
Dog myDog = new Dog();
myDog.Speak(); // Output: The dog barks.
Animal anotherDog = new Dog();
anotherDog.Speak(); // Output: The dog barks.
Here Dog inherits from Animal and overrides the Speak method to present a different implementation of it in this example.
Method Overloading
Method overloading means that we can have same method name with different parameters. The method signature is used to decide right method to invoke, i.e the method with method name as well as parameter types.
public class MathOperations
{
public int Multiply(int a, int b)
{
return a * b;
}
public double Multiply(double a, double b)
{
return a * b;
}
public int Multiply(int a, int b, int c)
{
return a * b * c;
}
}
// Usage
MathOperations math = new MathOperations();
Console.WriteLine(math.Multiply(2, 3)); // Calls first method
Console.WriteLine(math.Multiply(2.5, 3.5)); // Calls second method
Console.WriteLine(math.Multiply(2, 3, 4)); // Calls third method
Factors Affecting Method Overloading
Method overloading is determined by:
- Number of Parameters: Parameters different methods have.
- Type of Parameters: Different types of parameters used by methods.
- Order of Parameters: Methods whose order of types is different from the others.
Correct overloading does not just mean return type is different; the method signatures also should be different.
Recursion
When a method calls itself directly or indirectly to solve a problem, we call it as recursion. For tasks which we can break down into similar sub tasks, it’s useful.
public int Factorial(int n)
{
if (n <= 1)
return 1;
else
return n * Factorial(n - 1);
}
// Usage
Console.WriteLine(Factorial(5)); // Output: 120
In this example we have Factorial calling itself with a decremented value until it gets to the base case.
Extension Methods
Extension methods are a language addition which allows developers to extend types without having to create a new type or modify the original type. But they are static methods which can be called as if they were instance methods/methods on the extended type.
public static class StringExtensions
{
public static bool IsPalindrome(this string s)
{
var reversed = new string(s.Reverse().ToArray());
return s.Equals(reversed, StringComparison.OrdinalIgnoreCase);
}
}
// Usage
string word = "Level";
bool isPalindrome = word.IsPalindrome();
Console.WriteLine(isPalindrome); // Output: True
The IsPalindrome method is extended to the string type, so that all string instances can use this method.
Async Methods
As a way to achieve asynchronous operations, without blocking the calling thread, we use async methods. Async modifier and sometimes await keywords are very often used to wait for tasks completion.
public async Task<string> FetchDataAsync(string url)
{
using (HttpClient client = new HttpClient())
{
string result = await client.GetStringAsync(url);
return result;
}
}
// Usage
string data = await FetchDataAsync("https://api.example.com/data");
Console.WriteLine(data);
Fetching data from a URL in an asynchronous way (as other things can be run concurrently).
Expression-bodied Members
Expression bodied members allow a brief syntax for methods or properties having a single expression. They use the => operator.
Expression-bodied Method
public class Calculator
{
public int Square(int x) => x * x;
}
// Usage
Calculator calc = new Calculator();
Console.WriteLine(calc.Square(5)); // Output: 25
Expression-bodied Property
public class Person
{
private string firstName;
private string lastName;
public string FullName => $"{firstName} {lastName}";
}
In these examples, the methods and properties are defined with more concise syntax.
yield return
In iterator methods, the algorithm is to provide you with a value by enumerator object one by one using yield return statement. It makes it easier to implement arbitrary iteration without having to do it through the temporary collections interface.
public IEnumerable<int> GetEvenNumbers(int max)
{
for (int i = 0; i <= max; i++)
{
if (i % 2 == 0)
yield return i;
}
}
// Usage
foreach (int number in GetEvenNumbers(10))
{
Console.WriteLine(number);
}
This returns even numbers, up to some max value (inclusive), the immediate result of each number.
Understanding and using good methods, developers can write more organized, reusable, and maintainable code using C# language. Including necessary parts of a methodology from basic declarations to more advanced features, this guide is a solid foundation for creating robust applications.