Introduction to C#
C# (pronounced “C-sharp”) is a modern, object-oriented programming language developed by Microsoft as part of the .NET framework. It combines the power of C++ with the simplicity of Visual Basic, offering a versatile language for building Windows applications, web services, games, mobile apps, and more.
Why C# Matters:
- Versatile language for various application types
- Strong typing reduces errors and improves reliability
- Robust memory management with garbage collection
- Extensive standard library and third-party support
- Cross-platform capabilities with .NET Core/.NET 5+
Core C# Concepts
Data Types
Category | Types | Examples | Size/Range |
---|
Value Types | | | |
Integer | byte , sbyte , short , ushort , int , uint , long , ulong | int age = 25; | int : 32-bit (-2^31 to 2^31-1) |
Floating Point | float , double , decimal | double price = 19.99; | double : 64-bit |
Boolean | bool | bool isActive = true; | 8-bit (true/false) |
Character | char | char grade = 'A'; | 16-bit (Unicode) |
Reference Types | | | |
String | string | string name = "John"; | Variable |
Object | object | object obj = new Person(); | Variable |
Class | User-defined | Person p = new Person(); | Variable |
Interface | User-defined | IComparable ic; | Variable |
Arrays | Various | int[] numbers = {1, 2, 3}; | Variable |
Variables and Constants
// Variable declaration and initialization
int age = 30;
string name = "Alice";
// Constants (values that cannot be changed)
const double Pi = 3.14159;
// Implicit typing with var
var count = 10; // Compiler infers type as int
var message = "Hello"; // Compiler infers type as string
// Nullable types
int? nullableInt = null;
Operators
Category | Operators | Example |
---|
Arithmetic | + , - , * , / , % , ++ , -- | int sum = a + b; |
Comparison | == , != , < , > , <= , >= | if (age > 18) |
Logical | && , ` | |
Bitwise | & , ` | , ^, ~, <<, >>` |
Assignment | = , += , -= , *= , /= , etc. | total += value; |
Null-related | ?? , ?. , ??= | string name = value ?? "Default"; |
Control Flow
Conditional Statements
// If-else statement
if (condition)
{
// Code to execute if condition is true
}
else if (anotherCondition)
{
// Code to execute if anotherCondition is true
}
else
{
// Code to execute if all conditions are false
}
// Switch statement
switch (variable)
{
case value1:
// Code for value1
break;
case value2:
// Code for value2
break;
default:
// Default code
break;
}
// Ternary operator
string status = (age >= 18) ? "Adult" : "Minor";
// Pattern matching (C# 7.0+)
if (obj is string s)
{
// Use s as a string
}
// Switch expressions (C# 8.0+)
string result = x switch
{
0 => "Zero",
1 => "One",
_ => "Other"
};
Loops
// For loop
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
// While loop
while (condition)
{
// Code executed as long as condition is true
}
// Do-while loop
do
{
// Code executed at least once
} while (condition);
// Foreach loop
foreach (var item in collection)
{
Console.WriteLine(item);
}
// Loop control
break; // Exit the loop
continue; // Skip to next iteration
Object-Oriented Programming in C#
Classes and Objects
// Class definition
public class Person
{
// Fields (private by convention)
private string _name;
private int _age;
// Properties
public string Name
{
get { return _name; }
set { _name = value; }
}
// Auto-implemented property
public int Age { get; set; }
// Constructors
public Person() // Default constructor
{
_name = "Unknown";
_age = 0;
}
public Person(string name, int age) // Parameterized constructor
{
_name = name;
_age = age;
}
// Methods
public void Introduce()
{
Console.WriteLine($"Hi, I'm {_name} and I'm {_age} years old.");
}
// Static members (belong to the class, not instances)
public static int InstanceCount = 0;
}
// Creating objects
Person person1 = new Person();
Person person2 = new Person("John", 30);
// Object initializer syntax
Person person3 = new Person { Name = "Alice", Age = 25 };
Inheritance and Polymorphism
// Base class
public class Animal
{
public string Name { get; set; }
public virtual void MakeSound()
{
Console.WriteLine("Some generic animal sound");
}
}
// Derived class
public class Dog : Animal
{
public string Breed { get; set; }
// Method overriding
public override void MakeSound()
{
Console.WriteLine("Woof!");
}
}
// Using polymorphism
Animal myPet = new Dog();
myPet.MakeSound(); // Outputs: "Woof!"
Access Modifiers
Modifier | Access Level |
---|
public | Accessible from any code |
private | Accessible only within the containing type |
protected | Accessible within the containing type and derived types |
internal | Accessible within the same assembly |
protected internal | Accessible within the same assembly or derived types |
private protected | Accessible within the containing type or derived types in the same assembly |
Advanced C# Features
Exception Handling
try
{
// Code that might throw an exception
int result = 10 / userInput;
}
catch (DivideByZeroException ex)
{
// Handle specific exception
Console.WriteLine("Cannot divide by zero!");
}
catch (Exception ex)
{
// Handle any other exception
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
// Code that always executes (optional)
Console.WriteLine("Operation completed");
}
// Throwing exceptions
throw new ArgumentException("Invalid parameter value");
// Using exception filters (C# 6.0+)
try
{
// Code
}
catch (Exception ex) when (ex.InnerException != null)
{
// Only catches exceptions with inner exceptions
}
Delegates and Events
// Delegate declaration
public delegate void MessageHandler(string message);
// Event using delegate
public event MessageHandler OnMessageReceived;
// Lambda expressions and anonymous methods
MessageHandler handler = (message) => Console.WriteLine(message);
// Action and Func delegates
Action<string> printAction = message => Console.WriteLine(message);
Func<int, int, int> add = (a, b) => a + b;
LINQ (Language Integrated Query)
// LINQ query syntax
var result = from num in numbers
where num > 5
orderby num descending
select num;
// LINQ method syntax
var result = numbers
.Where(n => n > 5)
.OrderByDescending(n => n)
.Select(n => n);
// Common LINQ operations
var firstItem = collection.First();
var anyMatch = collection.Any(x => x.Property == value);
var groupedData = collection.GroupBy(x => x.Category);
var sum = numbers.Sum();
var average = numbers.Average();
Asynchronous Programming
// Async method declaration
public async Task<string> GetDataAsync()
{
// Asynchronous operation
string result = await httpClient.GetStringAsync(url);
return result;
}
// Calling async methods
string data = await GetDataAsync();
// Task-based parallel operations
await Task.WhenAll(task1, task2, task3);
// Cancellation support
CancellationTokenSource cts = new CancellationTokenSource();
await LongRunningTaskAsync(cts.Token);
// Later: cts.Cancel();
File I/O and Serialization
File Operations
// Reading text
string content = File.ReadAllText("file.txt");
string[] lines = File.ReadAllLines("file.txt");
// Writing text
File.WriteAllText("output.txt", content);
File.AppendAllText("log.txt", newEntry);
// File streams
using (StreamReader reader = new StreamReader("input.txt"))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
// Process line
}
}
using (StreamWriter writer = new StreamWriter("output.txt"))
{
writer.WriteLine("Hello, World!");
}
JSON Serialization
// Requires System.Text.Json or Newtonsoft.Json
// Serializing object to JSON
string json = JsonSerializer.Serialize(person);
// Deserializing JSON to object
Person person = JsonSerializer.Deserialize<Person>(json);
// Serialization options
var options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
Common C# Challenges and Solutions
Null Reference Exceptions
// Null checking
if (object != null)
{
// Use object safely
}
// Null conditional operator
string name = person?.Name; // Returns null if person is null
// Null coalescing operator
string displayName = name ?? "Unknown"; // Use "Unknown" if name is null
// Null reference types (C# 8.0+)
#nullable enable
string? nullableName; // Can be null
string nonNullableName = "John"; // Cannot be null
String Manipulation
// String concatenation
string fullName = firstName + " " + lastName;
// String interpolation
string greeting = $"Hello, {firstName}!";
// String builder (for multiple operations)
StringBuilder sb = new StringBuilder();
sb.Append("Hello");
sb.Append(", ");
sb.Append(name);
string result = sb.ToString();
// Common string methods
string lower = text.ToLower();
string trimmed = text.Trim();
bool contains = text.Contains("search");
string replaced = text.Replace("old", "new");
string[] parts = text.Split(',');
Collection Performance
Collection | Scenario | Advantages | Disadvantages |
---|
List<T> | General-purpose | Fast access by index, dynamic sizing | Slow insertion/removal within list |
Dictionary<K,V> | Key-value lookups | Very fast lookups, insertion, deletion | Higher memory usage |
HashSet<T> | Unique elements | Fast lookup, checks for duplicates | No indexing |
Queue<T> | FIFO processing | Efficient enqueue/dequeue | No random access |
Stack<T> | LIFO processing | Efficient push/pop | No random access |
LinkedList<T> | Frequent insertions | Fast insertion/deletion anywhere | Slow lookup |
Best Practices for C# Development
Coding Standards
- Use PascalCase for class names, public members, and method names
- Use camelCase for local variables and parameters
- Use meaningful names that describe purpose
- Use proper XML documentation comments
- Follow the C# design guidelines from Microsoft
Performance Tips
- Use
StringBuilder
for string concatenation in loops - Prefer
for
over foreach
for performance-critical code - Implement
IDisposable
for proper resource management - Consider using structs for small, value-type objects
- Use the appropriate collection for the use case
- Avoid unnecessary boxing/unboxing
- Use async/await for I/O-bound operations
Security Best Practices
- Never trust user input – always validate and sanitize
- Use parameterized queries to prevent SQL injection
- Avoid storing sensitive information in plain text
- Implement proper authentication and authorization
- Be careful with serialization/deserialization of untrusted data
- Use secure communication channels (HTTPS)
- Keep dependencies updated to address security vulnerabilities
Development Tools and Environment
Key Development Tools
- Visual Studio: Full-featured IDE for Windows
- Visual Studio Code: Lightweight, cross-platform editor
- JetBrains Rider: Alternative cross-platform IDE
- ReSharper: Productivity tool for Visual Studio
- NuGet: Package manager for .NET
Debugging Techniques
- Using breakpoints and step through code
- Watch windows for variable inspection
- Immediate window for code execution
- Exception settings to catch specific exceptions
- Diagnostic tools for memory and performance analysis
Resources for Further Learning
Official Documentation
Books
- “C# in Depth” by Jon Skeet
- “C# 9.0 in a Nutshell” by Joseph Albahari
- “Clean Code” by Robert C. Martin (general programming principles)
Online Learning
- Microsoft Learn
- Pluralsight
- Coursera and edX .NET courses
- Stack Overflow for community support
Community Resources
- .NET Foundation
- C# Corner
- GitHub sample projects and repositories
- Microsoft Developer blogs