Expression-Bodied Members, Null-Conditional Operator, String Interpolation, Auto-Property Initializers, nameof operator, Exception Filters

 

1. Expression-Bodied Members

Expression-bodied members allow you to write concise methods, properties, or constructors using a single line of code with the => syntax. This makes your code more compact and readable when the logic is simple.

Example: Expression-Bodied Methods and Properties

class Person { public string FirstName { get; } public string LastName { get; } // Expression-bodied constructor public Person(string firstName, string lastName) => (FirstName, LastName) = (firstName, lastName); // Expression-bodied method public string GetFullName() => $"{FirstName} {LastName}"; // Expression-bodied property public string FullName => $"{FirstName} {LastName}"; } class Program { static void Main() { var person = new Person("John", "Doe"); Console.WriteLine(person.GetFullName()); // Output: John Doe Console.WriteLine(person.FullName); // Output: John Doe } }

How It Works:

  • The Person constructor is defined in a single line using the => syntax.
  • The GetFullName method and FullName property are also written as single-line expressions. This is useful for simple return statements or property calculations.

2. Null-Conditional Operators

The null-conditional operator ?. and the null-coalescing operator ?? help you write safer code when dealing with potentially null objects, avoiding NullReferenceException errors.

  • ?. checks if an object is null before accessing its members. If the object is null, the entire expression evaluates to null.
  • ?? provides a default value if the left-hand side is null.

Example: Null-Conditional and Null-Coalescing Operators

class Program { class Address { public string Street { get; set; } } class Person { public Address Address { get; set; } } static void Main() { Person person = new Person(); // Null-conditional operator string street = person?.Address?.Street; Console.WriteLine(street ?? "Street not found"); // Output: Street not found // Null-coalescing operator string defaultName = null; string name = defaultName ?? "Unknown"; Console.WriteLine(name); // Output: Unknown } }

How It Works:

  • The ?. operator safely navigates the person object to access the Street property. If any object in the chain is null, the expression returns null.
  • The ?? operator provides a fallback value ("Unknown") if defaultName is null.

3. String Interpolation

String interpolation allows you to embed expressions inside string literals, simplifying string formatting by using the $"{}" syntax. This is more readable than concatenation or string.Format.

Example: String Interpolation

class Program { static void Main() { string name = "Alice"; int age = 30; // String interpolation string message = $"Name: {name}, Age: {age}"; Console.WriteLine(message); // Output: Name: Alice, Age: 30 } }

How It Works:

  • The $"{}" syntax allows you to directly embed variables and expressions (like name and age) inside the string, making it much cleaner than traditional concatenation.

4. Auto-Property Initializers

Auto-property initializers allow you to initialize properties with default values directly when they are declared. This avoids the need to set default values in constructors.

Example: Auto-Property Initializers

class Program { class Person { // Auto-property initializer public string Name { get; set; } = "Unknown"; public int Age { get; set; } = 18; } static void Main() { var person = new Person(); Console.WriteLine($"Name: {person.Name}, Age: {person.Age}"); // Output: Name: Unknown, Age: 18 } }

How It Works:

  • The Name and Age properties are initialized with default values directly in their declarations. These values are assigned if no other values are provided.

5. nameof Operator

The nameof operator returns the name of a variable, method, or property as a string. This is useful for refactoring-safe code, especially in exception messages, argument checks, or logging.

Example: nameof Operator

class Program { static void ValidateAge(int age) { if (age < 0) throw new ArgumentException($"Invalid argument: {nameof(age)} cannot be negative."); } static void Main() { try { ValidateAge(-5); // This will throw an exception } catch (ArgumentException ex) { Console.WriteLine(ex.Message); // Output: Invalid argument: age cannot be negative. } } }

How It Works:

  • The nameof(age) returns the string "age". This is helpful when you want to reference the name of a variable or parameter, ensuring that the name stays correct even if refactored.

6. Exception Filters

Exception filters allow you to specify conditions in catch blocks, so exceptions are only caught if they satisfy a particular condition. This can prevent unnecessary catching of exceptions and make exception handling more precise.

Example: Exception Filters

class Program { static void Main() { try { ThrowException(); } catch (Exception ex) when (ex is InvalidOperationException) { Console.WriteLine("Caught an InvalidOperationException."); } catch (Exception ex) when (ex.Message.Contains("specific")) { Console.WriteLine("Caught an exception with 'specific' in the message."); } } static void ThrowException() { throw new InvalidOperationException("This is a specific error message."); } }

How It Works:

  • The first catch block with the exception filter when (ex is InvalidOperationException) catches only InvalidOperationException.
  • The second catch block checks if the exception message contains the word "specific". This allows you to filter exceptions based on custom logic.

Summary of Key Points

  1. Expression-Bodied Members: Use the => syntax for one-liner methods, properties, and constructors, leading to more concise code.
  2. Null-Conditional Operators: Use ?. and ?? to safely access members of potentially null objects and provide default values.
  3. String Interpolation: Simplifies string formatting by embedding expressions directly in string literals with $"{}".
  4. Auto-Property Initializers: Allows properties to be initialized with default values at the point of declaration.
  5. nameof Operator: Retrieves the name of a variable, method, or property as a string, useful for refactoring-safe code.
  6. Exception Filters: Allows more precise exception handling by specifying conditions that an exception must satisfy before being caught.

Post a Comment