Skip to main content

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#:

csharp
// 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:

csharp
// 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:

csharp
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:

csharp
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

csharp
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:

csharp
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

csharp
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

csharp
// 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:

csharp
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:

csharp
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

csharp
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

csharp
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

csharp
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:

  1. String immutability: Each string operation creates a new string, which can be inefficient in loops.
  2. Use StringBuilder: For frequent string modifications, use StringBuilder instead of string concatenation.
  3. StringPool: C# maintains a "string pool" for reusing string literals, which helps save memory.
  4. Interning: You can manually intern strings using String.Intern() to save memory when dealing with many duplicate strings.
csharp
// 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

Exercises

  1. Palindrome Checker: Write a function that checks if a string is a palindrome (reads the same backward as forward), ignoring spaces, punctuation, and case.

  2. CSV Parser: Create a program that reads a CSV string and converts it into a list of objects with properties.

  3. 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.

  4. 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).

  5. 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! :)