C# Strings
Introduction
Strings are one of the most commonly used data types in programming. In C#, a string represents a sequence of characters (text) that is stored as a collection of Unicode characters. Whether you need to store a name, address, or any textual information, strings are essential for handling text data in your applications.
In this lesson, we'll explore how to create, manipulate, and work with strings in C#. We'll cover string declaration, common operations, useful methods, and practical examples to help you master string handling in your C# applications.
What is a String in C#?
In C#, a string is an object of type String
from the System
namespace. Strings are immutable, which means once a string is created, its contents cannot be changed - any modification creates a new string object.
String Declaration and Initialization
There are several ways to declare and initialize strings in C#:
// Basic string declaration and initialization
string greeting = "Hello, World!";
// Empty string
string emptyString = "";
// Null string
string nullString = null;
// String with special characters using escape sequences
string path = "C:\\Program Files\\MyApp"; // Backslashes need to be escaped
// Verbatim string literal (preserves all whitespace and backslashes)
string verbatimPath = @"C:\Program Files\MyApp";
// String concatenation at declaration
string fullName = "John" + " " + "Doe";
// String interpolation (available in C# 6.0 and later)
string firstName = "John";
string lastName = "Doe";
string interpolatedName = $"My name is {firstName} {lastName}";
Basic String Operations
String Concatenation
You can combine strings using the +
operator or the string.Concat()
method:
// Using + operator
string firstName = "John";
string lastName = "Doe";
string fullName = firstName + " " + lastName;
Console.WriteLine(fullName); // Output: John Doe
// Using string.Concat()
string greeting = string.Concat("Hello, ", firstName, "!");
Console.WriteLine(greeting); // Output: Hello, John!
String Interpolation
String interpolation provides a more readable way to include expressions in string literals:
string name = "Maria";
int age = 25;
string message = $"{name} is {age} years old.";
Console.WriteLine(message); // Output: Maria is 25 years old.
// You can include expressions
string result = $"2 + 2 = {2 + 2}";
Console.WriteLine(result); // Output: 2 + 2 = 4
String Length
You can find the length of a string using the Length
property:
string text = "Hello, World!";
int length = text.Length;
Console.WriteLine($"The string has {length} characters."); // Output: The string has 13 characters.
Common String Methods
C# provides numerous methods for string manipulation. Let's explore some of the most commonly used ones:
Searching Within Strings
string sentence = "The quick brown fox jumps over the lazy dog.";
// Check if a string contains a substring
bool containsFox = sentence.Contains("fox");
Console.WriteLine($"Contains 'fox': {containsFox}"); // Output: Contains 'fox': True
// Find the position of a substring
int indexOfBrown = sentence.IndexOf("brown");
Console.WriteLine($"Index of 'brown': {indexOfBrown}"); // Output: Index of 'brown': 10
// Check if string starts or ends with specific text
bool startsWithThe = sentence.StartsWith("The");
bool endsWithDot = sentence.EndsWith(".");
Console.WriteLine($"Starts with 'The': {startsWithThe}"); // Output: Starts with 'The': True
Console.WriteLine($"Ends with '.': {endsWithDot}"); // Output: Ends with '.': True
Modifying Strings
Remember that strings are immutable, so these methods return new strings:
string original = " Hello, World! ";
// Remove whitespace from beginning and end
string trimmed = original.Trim();
Console.WriteLine($"Trimmed: '{trimmed}'"); // Output: Trimmed: 'Hello, World!'
// Change case
string upperCase = trimmed.ToUpper();
string lowerCase = trimmed.ToLower();
Console.WriteLine($"Upper case: {upperCase}"); // Output: Upper case: HELLO, WORLD!
Console.WriteLine($"Lower case: {lowerCase}"); // Output: Lower case: hello, world!
// Replace parts of a string
string replaced = trimmed.Replace("Hello", "Hi");
Console.WriteLine(replaced); // Output: Hi, World!
Substring Extraction
string sentence = "The quick brown fox";
// Extract substring (starting at position 4, taking 5 characters)
string substringResult = sentence.Substring(4, 5);
Console.WriteLine(substringResult); // Output: quick
// Extract from position to the end
string endPart = sentence.Substring(10);
Console.WriteLine(endPart); // Output: brown fox
Splitting and Joining Strings
// Split a string into an array based on a delimiter
string csvData = "John,Doe,32,New York";
string[] parts = csvData.Split(',');
Console.WriteLine("Split results:");
foreach (var part in parts)
{
Console.WriteLine(part);
}
// Output:
// John
// Doe
// 32
// New York
// Join array elements into a string
string[] words = { "Hello", "beautiful", "world" };
string joined = string.Join(" ", words);
Console.WriteLine(joined); // Output: Hello beautiful world
String Comparison
Comparing strings correctly is important, especially in scenarios involving user input or data from different cultures:
string str1 = "Hello";
string str2 = "hello";
// Case-sensitive comparison (returns false)
bool areEqual = str1 == str2;
Console.WriteLine($"Using == operator: {areEqual}"); // Output: Using == operator: False
// Case-insensitive comparison
bool areEqualIgnoreCase = str1.Equals(str2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine($"Case-insensitive comparison: {areEqualIgnoreCase}"); // Output: Case-insensitive comparison: True
// Compare for sorting (returns negative when str1 < str2, 0 when equal, positive when str1 > str2)
int compareResult = string.Compare(str1, str2);
Console.WriteLine($"Compare result: {compareResult}"); // Output: Compare result: -32 (varies by platform)
String Builder
When performing many string operations in a loop, using the StringBuilder
class from the System.Text
namespace is more efficient than repeated string concatenation:
using System;
using System.Text;
public class Program
{
public static void Main()
{
// Inefficient way (creates many temporary string objects)
string result = "";
for (int i = 0; i < 10; i++)
{
result += $"Item {i}, ";
}
Console.WriteLine(result);
// More efficient way using StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++)
{
sb.Append($"Item {i}, ");
}
string efficientResult = sb.ToString();
Console.WriteLine(efficientResult);
}
}
Practical Examples
Example 1: Name Parser
public static void ParseName()
{
Console.WriteLine("Enter a full name (first middle last):");
string fullName = Console.ReadLine();
// Split the name into parts
string[] nameParts = fullName.Split(' ');
if (nameParts.Length >= 3)
{
string firstName = nameParts[0];
string middleInitial = nameParts[1][0] + ".";
string lastName = nameParts[2];
Console.WriteLine($"Formatted name: {lastName}, {firstName} {middleInitial}");
}
else if (nameParts.Length == 2)
{
string firstName = nameParts[0];
string lastName = nameParts[1];
Console.WriteLine($"Formatted name: {lastName}, {firstName}");
}
else
{
Console.WriteLine("Please enter at least a first and last name.");
}
}
// Example Input: John Robert Smith
// Example Output: Formatted name: Smith, John R.
Example 2: Email Validator
public static bool IsValidEmail(string email)
{
// Basic email validation
if (string.IsNullOrWhiteSpace(email))
return false;
// Check for @ symbol and proper domain
int atIndex = email.IndexOf('@');
if (atIndex <= 0 || atIndex == email.Length - 1)
return false;
// Check for domain with at least one dot
int dotIndex = email.IndexOf('.', atIndex);
if (dotIndex == -1 || dotIndex == email.Length - 1)
return false;
return true;
}
// Test the method
public static void TestEmailValidator()
{
string[] emails = {
"[email protected]",
"invalid-email",
"no@domain.",
"@nodomain.com",
"[email protected]"
};
foreach (var email in emails)
{
Console.WriteLine($"Email: {email} - Valid: {IsValidEmail(email)}");
}
}
// Output:
// Email: [email protected] - Valid: True
// Email: invalid-email - Valid: False
// Email: no@domain. - Valid: False
// Email: @nodomain.com - Valid: False
// Email: [email protected] - Valid: True
Example 3: Word Counter
public static void CountWords(string text)
{
// Remove punctuation and normalize whitespace
string cleanText = new string(text.Select(c => char.IsPunctuation(c) ? ' ' : c).ToArray());
cleanText = string.Join(" ", cleanText.Split(new[] { ' ' },
StringSplitOptions.RemoveEmptyEntries));
// Split into words and count
string[] words = cleanText.Split(' ');
// Count occurrences of each word
Dictionary<string, int> wordCount = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
foreach (string word in words)
{
if (wordCount.ContainsKey(word))
wordCount[word]++;
else
wordCount[word] = 1;
}
// Display results
Console.WriteLine($"Total words: {words.Length}");
Console.WriteLine("Word frequencies:");
foreach (var pair in wordCount.OrderByDescending(p => p.Value))
{
Console.WriteLine($" {pair.Key}: {pair.Value}");
}
}
// Example Input:
// "The quick brown fox jumps over the lazy dog. The dog was not very lazy after all."
//
// Example Output:
// Total words: 16
// Word frequencies:
// the: 3
// lazy: 2
// dog: 2
// quick: 1
// brown: 1
// ... and so on
String Performance Considerations
When working with strings, keep these performance tips in mind:
- String immutability: Each string operation creates a new string, which can be inefficient in loops.
- Use StringBuilder: For frequent string modifications, use
StringBuilder
instead of string concatenation. - StringPool: C# maintains a "string pool" for reusing string literals, which helps save memory.
- Interning: You can manually intern strings using
String.Intern()
to save memory when dealing with many duplicate strings.
// Example of string interning
string s1 = "Hello";
string s2 = new string(new char[] { 'H', 'e', 'l', 'l', 'o' });
Console.WriteLine(object.ReferenceEquals(s1, s2)); // Output: False
// After interning, they point to the same string in the pool
string s3 = string.Intern(s2);
Console.WriteLine(object.ReferenceEquals(s1, s3)); // Output: True
Summary
In this lesson, we've covered:
- How to create and initialize strings in C#
- Basic string operations like concatenation and interpolation
- Common string methods for searching, modifying, and extracting
- String comparison and the importance of using the correct comparison methods
- Efficient string manipulation using StringBuilder
- Practical examples demonstrating string handling in real-world scenarios
Strings are fundamental to almost any application, and mastering string manipulation in C# will help you handle text data efficiently in your programs.
Additional Resources and Exercises
Resources
- Microsoft Documentation on String Class
- C# String Interpolation Documentation
- String vs StringBuilder in C#
Exercises
-
Palindrome Checker: Write a function that checks if a string is a palindrome (reads the same backward as forward), ignoring spaces, punctuation, and case.
-
CSV Parser: Create a program that reads a CSV string and converts it into a list of objects with properties.
-
String Encryption: Implement a simple encryption algorithm (like Caesar cipher) that shifts each letter in a string by a certain number of positions in the alphabet.
-
Word Scrambler: Write a function that takes a sentence and randomly scrambles the inner letters of each word (keeping the first and last letters in place).
-
String Formatter: Create a method that formats phone numbers into a standardized format (e.g., (123) 456-7890) regardless of the input format.
Remember, the best way to master strings in C# is through consistent practice. Try to incorporate string manipulation into your projects whenever possible!
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)