C# & ASP.NET Topic
C# Methods & Parameters
Method Fundamentals
Basic Method Syntax
csharp
access_modifier return_type MethodName(parameter_list)
{
// method body
return value; // if return_type is not void
}
Simple Method Examples
csharp
using System;
class MethodExamples
{
// Method with no parameters and no return value
public void Greet()
{
Console.WriteLine("Hello, World!");
}
// Method with parameters and return value
public int Add(int a, int b)
{
return a + b;
}
// Method with string return type
public string GetFullName(string firstName, string lastName)
{
return $"{firstName} {lastName}";
}
// Method with boolean return type
public bool IsAdult(int age)
{
return age >= 18;
}
}
Return Types
Void Methods
csharp
public void DisplayMessage(string message)
{
Console.WriteLine($"Message: {message}");
// No return statement needed for void
}
public void ProcessData(int data)
{
if (data < 0)
return; // Early return allowed in void methods
Console.WriteLine($"Processing: {data}");
}
Value-Returning Methods
csharp
// Primitive types
public int CalculateSquare(int number)
{
return number * number;
}
public double CalculateCircleArea(double radius)
{
return Math.PI * radius * radius;
}
public bool ValidateEmail(string email)
{
return !string.IsNullOrEmpty(email) && email.Contains("@");
}
// Using expressions for simple methods
public int Multiply(int x, int y) => x * y;
public bool IsEven(int number) => number % 2 == 0;
Complex Return Types
csharp
// Returning arrays
public int[] GetEvenNumbers(int count)
{
int[] numbers = new int[count];
for (int i = 0; i < count; i++)
{
numbers[i] = i * 2;
}
return numbers;
}
// Returning custom objects
public Person CreatePerson(string name, int age)
{
return new Person { Name = name, Age = age };
}
// Returning tuples (C# 7.0+)
public (int sum, int product) Calculate(int a, int b)
{
return (a + b, a * b);
}
// Using named tuple elements
public (int Addition, int Multiplication) Compute(int x, int y)
{
return (x + y, x * y);
}
Method Parameters
Value Parameters (Default)
csharp
public void ValueParameterExample(int number)
{
number = 100; // Changes only the local copy
Console.WriteLine($"Inside method: {number}");
}
// Usage
int original = 50;
ValueParameterExample(original);
Console.WriteLine($"Outside: {original}"); // Still 50
Reference Parameters (ref)
csharp
public void ModifyWithRef(ref int number)
{
number = 100; // Modifies the original variable
Console.WriteLine($"Inside method: {number}");
}
// Usage
int value = 50;
Console.WriteLine($"Before: {value}"); // 50
ModifyWithRef(ref value); // Must use 'ref' keyword
Console.WriteLine($"After: {value}"); // 100
Output Parameters (out)
csharp
public void TryDivide(int dividend, int divisor, out int result, out int remainder)
{
if (divisor != 0)
{
result = dividend / divisor;
remainder = dividend % divisor;
}
else
{
result = 0;
remainder = 0;
}
}
// Usage
int quotient, remainder;
TryDivide(17, 5, out quotient, out remainder);
Console.WriteLine($"17 / 5 = {quotient} remainder {remainder}");
// C# 7.0+ - inline variable declaration
TryDivide(20, 3, out int result, out int rem);
Console.WriteLine($"20 / 3 = {result} remainder {rem}");
ref vs out Comparison
csharp
public class RefOutComparison
{
// ref parameter - must be initialized before passing
public void RefExample(ref int number)
{
number *= 2; // Can read and modify
}
// out parameter - doesn't need initialization
public void OutExample(out int number)
{
number = 42; // Must assign before returning
// Can't read before assigning
}
public void Demonstrate()
{
// ref usage
int refValue = 10; // Must be initialized
RefExample(ref refValue);
Console.WriteLine($"refValue: {refValue}"); // 20
// out usage
int outValue; // Doesn't need initialization
OutExample(out outValue);
Console.WriteLine($"outValue: {outValue}"); // 42
}
}
Parameter Arrays (params)
csharp
public int Sum(params int[] numbers)
{
int total = 0;
foreach (int number in numbers)
{
total += number;
}
return total;
}
// Usage
int result1 = Sum(1, 2, 3); // 6
int result2 = Sum(10, 20, 30, 40); // 100
int result3 = Sum(); // 0
// Can also pass array
int[] array = { 5, 10, 15 };
int result4 = Sum(array); // 30
Optional Parameters
csharp
public void Configure(string name, int timeout = 30, bool enabled = true)
{
Console.WriteLine($"Name: {name}, Timeout: {timeout}, Enabled: {enabled}");
}
// Usage
Configure("Server"); // timeout=30, enabled=true
Configure("Database", 60); // timeout=60, enabled=true
Configure("Cache", 10, false); // timeout=10, enabled=false
// Named parameters (order doesn't matter)
Configure(name: "API", enabled: false, timeout: 15);
Method Overloading
Basic Overloading
csharp
public class Calculator
{
// Same method name, different parameters
// Integer version
public int Add(int a, int b)
{
return a + b;
}
// Double version
public double Add(double a, double b)
{
return a + b;
}
// Three parameters
public int Add(int a, int b, int c)
{
return a + b + c;
}
// Array version
public int Add(params int[] numbers)
{
int sum = 0;
foreach (int num in numbers)
{
sum += num;
}
return sum;
}
}
// Usage
Calculator calc = new Calculator();
Console.WriteLine(calc.Add(5, 10)); // 15 - calls int version
Console.WriteLine(calc.Add(5.5, 10.5)); // 16.0 - calls double version
Console.WriteLine(calc.Add(1, 2, 3)); // 6 - calls three-parameter version
Console.WriteLine(calc.Add(1, 2, 3, 4, 5)); // 15 - calls params version
Advanced Overloading Examples
csharp
public class StringProcessor
{
// Process single string
public string Process(string input)
{
return input.ToUpper();
}
// Process string with prefix
public string Process(string input, string prefix)
{
return $"{prefix}{input}";
}
// Process with transformation function
public string Process(string input, Func<string, string> transformer)
{
return transformer(input);
}
// Process multiple strings
public string[] Process(params string[] inputs)
{
string[] results = new string[inputs.Length];
for (int i = 0; i < inputs.Length; i++)
{
results[i] = inputs[i].ToUpper();
}
return results;
}
}
Constructor Overloading
csharp
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
// Default constructor
public Person()
{
Name = "Unknown";
Age = 0;
Email = string.Empty;
}
// Constructor with name
public Person(string name)
{
Name = name;
Age = 0;
Email = string.Empty;
}
// Constructor with name and age
public Person(string name, int age)
{
Name = name;
Age = age;
Email = string.Empty;
}
// Constructor with all properties
public Person(string name, int age, string email)
{
Name = name;
Age = age;
Email = email;
}
}
// Usage
Person person1 = new Person();
Person person2 = new Person("John");
Person person3 = new Person("Jane", 25);
Person person4 = new Person("Bob", 30, "bob@email.com");
Practical Examples
Mathematical Calculator with Overloading
csharp
public class AdvancedCalculator
{
// Basic operations with different types
public int Add(int a, int b) => a + b;
public double Add(double a, double b) => a + b;
public decimal Add(decimal a, decimal b) => a + b;
// Operations with three parameters
public int Add(int a, int b, int c) => a + b + c;
// Array operations
public int Sum(params int[] numbers)
{
int total = 0;
foreach (int num in numbers)
{
total += num;
}
return total;
}
public double Average(params double[] numbers)
{
if (numbers.Length == 0) return 0;
double sum = 0;
foreach (double num in numbers)
{
sum += num;
}
return sum / numbers.Length;
}
// Using out parameters for multiple returns
public bool TryCalculate(int a, int b, out int sum, out int product)
{
sum = a + b;
product = a * b;
return true;
}
// Using ref for in-place modification
public void Square(ref int number)
{
number *= number;
}
}
Data Validation Utility
csharp
public class Validator
{
// Overloaded validation methods
public static bool IsValid(string input)
{
return !string.IsNullOrWhiteSpace(input);
}
public static bool IsValid(string input, int minLength)
{
return !string.IsNullOrWhiteSpace(input) && input.Length >= minLength;
}
public static bool IsValid(string input, int minLength, int maxLength)
{
return !string.IsNullOrWhiteSpace(input) &&
input.Length >= minLength &&
input.Length <= maxLength;
}
public static bool IsValidEmail(string email, out string errorMessage)
{
if (string.IsNullOrWhiteSpace(email))
{
errorMessage = "Email cannot be empty";
return false;
}
if (!email.Contains("@"))
{
errorMessage = "Email must contain @ symbol";
return false;
}
errorMessage = string.Empty;
return true;
}
// Number validation with ref parameter
public static bool TryParsePositiveNumber(string input, ref int result)
{
if (int.TryParse(input, out int number) && number > 0)
{
result = number;
return true;
}
return false;
}
}
Real-World Example: Configuration Manager
csharp
public class ConfigurationManager
{
private string _configFile;
// Constructor overloading
public ConfigurationManager()
{
_configFile = "appsettings.json";
}
public ConfigurationManager(string configFile)
{
_configFile = configFile;
}
// Method overloading for different data types
public void SetSetting(string key, string value)
{
Console.WriteLine($"Setting {key} = '{value}' (string)");
}
public void SetSetting(string key, int value)
{
Console.WriteLine($"Setting {key} = {value} (int)");
}
public void SetSetting(string key, bool value)
{
Console.WriteLine($"Setting {key} = {value} (bool)");
}
public void SetSetting(string key, double value)
{
Console.WriteLine($"Setting {key} = {value} (double)");
}
// Methods with out parameters for error handling
public bool TryGetString(string key, out string value)
{
// Simulate configuration lookup
if (key == "database")
{
value = "localhost";
return true;
}
value = string.Empty;
return false;
}
public bool TryGetInt(string key, out int value)
{
if (key == "port")
{
value = 8080;
return true;
}
value = 0;
return false;
}
// Using ref to update configuration
public void UpdateTimeout(ref int timeout, int newValue)
{
Console.WriteLine($"Updating timeout from {timeout} to {newValue}");
timeout = newValue;
}
}
// Usage example
class Program
{
static void Main()
{
var config = new ConfigurationManager();
// Method overloading in action
config.SetSetting("name", "MyApp");
config.SetSetting("port", 8080);
config.SetSetting("debug", true);
config.SetSetting("ratio", 1.5);
// Using out parameters
if (config.TryGetString("database", out string dbConnection))
{
Console.WriteLine($"Database: {dbConnection}");
}
// Using ref parameter
int timeout = 30;
config.UpdateTimeout(ref timeout, 60);
Console.WriteLine($"New timeout: {timeout}");
}
}
Best Practices
1. Method Naming
csharp
// Good - clear, descriptive names
public double CalculateCircleArea(double radius)
public bool TryParseNumber(string input, out int result)
public void SaveToDatabase(Customer customer)
// Avoid - vague names
public void Process()
public void DoWork()
2. Parameter Design
csharp
// Good - logical parameter order
public void CreateUser(string name, string email, int age)
// Use optional parameters for sensible defaults
public void Connect(string server, int port = 8080, int timeout = 30)
// Use out parameters for additional return values
public bool TryAuthenticate(string username, string password, out string errorMessage)
3. Overloading Guidelines
csharp
// Overload for different data types
public void Log(string message)
public void Log(string message, LogLevel level)
public void Log(Exception exception)
// Avoid confusing overloads
// public void Process(int number) and public void Process(double number)
// might be confusing if called with Process(5)
4. Return Type Considerations
csharp
// Use void for actions
public void SendEmail(string to, string subject)
// Use bool for success/failure
public bool SaveChanges()
// Use specific types for data retrieval
public Customer GetCustomer(int id)
// Use tuples for multiple related values
public (bool success, string message, int count) ValidateData()
Key Takeaways
-
refparameters must be initialized before passing and can be read/modified -
outparameters don't need initialization but must be assigned in the method -
Method overloading allows same method name with different parameters
-
paramskeyword enables variable number of arguments -
Optional parameters provide default values and make methods more flexible
-
Use meaningful return types that clearly indicate the method's purpose
-
Consider using
Trypattern withoutparameters for operations that might fail
This comprehensive coverage of C# methods and parameters will give you a solid foundation for writing flexible, maintainable, and robust C# code!
Comments (0)
No comments yet. Be the first to comment!