as Keyword
The as keyword is used to perform safe type conversions. It attempts to convert an object to a specified type. If the conversion fails, it returns null instead of throwing an exception.
object obj = "Hello, world!";
string str = obj as string;
if (str != null)
{
Console.WriteLine(str); // Output: Hello, world!
}
Explanation
In the example above, obj is an object of type string. Using the keyword, we attempt to convert obj to a string. If obj were not a string, str would be null instead of throwing an exception.
is Keyword
The keyword is used to check if an object is of a particular type. It returns a boolean value.
object obj = "Hello, world!";
if (obj is string)
{
Console.WriteLine((string)obj); // Output: Hello, world!
}
Explanation
In the example above, the keyword checks if obj is of type string. If true, we cast obj to string and print it.
The Difference Between as and is
- as performs the conversion and returns null if it fails.
- it checks the type and returns true or false.
object obj = 42;
string strAs = obj as string; // strAs will be null
bool isString = obj is string; // isString will be false
nameof Operator
The nameof the operator obtains the name of a variable, type, or member as a string constant.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Person person = new Person();
string firstName = nameof(person.FirstName); // Output: FirstName
Explanation
In the example above, nameof(person.FirstName) returns the string "FirstName".
Conditional (Null-Coalescing) Operator
The conditional access operator ?. is used to perform a member access or an element access operation only if the operand is non-null. If the operand is null, the operator returns null.
Person person = null;
string name = person?.FirstName; // name will be null
Explanation
In the example above, a person is null. Using the ?. operator, we attempt to access FirstName. Since the person is null, the name will also be null instead of throwing a NullReferenceException.
Pattern Matching
Pattern matching is used to test if an object is of a certain type or conforms to a pattern and can extract values from that object if it matches the pattern.
object obj = 42;
if (obj is int number)
{
Console.WriteLine(number); // Output: 42
}
Explanation
In the example above, the keyword checks if obj is an int. If true, it assigns the value to the number variable, and we print it.
Advanced Pattern Matching
Pattern matching can be more complex, involving switch statements and more intricate patterns.
public void DisplayInfo(object obj)
{
switch (obj)
{
case Person p:
Console.WriteLine($"Person: {p.FirstName} {p.LastName}");
break;
case int i when i > 0:
Console.WriteLine($"Positive integer: {i}");
break;
case null:
Console.WriteLine("Null value");
break;
default:
Console.WriteLine("Unknown type");
break;
}
}
Explanation
In the example above, the switch statement uses pattern matching to check the type of obj and perform different actions based on its type and value.
Conclusion
Understanding and utilizing these features in C# can significantly improve your code's readability, safety, and flexibility. The as and is keywords allow for safe type checking and conversion, while the nameof operator and conditional access operator provide convenient ways to handle variable names and null values. Pattern matching offers a powerful way to test and extract data from objects, enhancing your ability to write clean and maintainable code.