自动属性初始化器允许在声明属性时直接赋初始值。
public class Person
{
public string Name { get; set; } = "Unknown";
public int Age { get; set; } = 18;
}
class Program
{
static void Main()
{
var person = new Person();
Console.WriteLine($"{person.Name}, {person.Age}");
}
}
局部函数可以嵌套在方法内部,使代码更紧凑、易读,并且可以访问外部方法的局部变量。
public class Calculator
{
public int Add(int x, int y)
{
int AddInternal() => x + y;
return AddInternal();
}
}
class Program
{
static void Main()
{
var calc = new Calculator();
Console.WriteLine(calc.Add(5, 3));
}
}
索引初始化器允许通过索引来初始化集合对象。
var dict = new Dictionary<int, string>
{
[1] = "One",
[2] = "Two",
[3] = "Three"
};
foreach (var item in dict)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
扩展方法允许你为现有类型添加新功能,而无需修改原类型代码。
public static class StringExtensions
{
public static string ReverseString(this string str)
{
return new string(str.Reverse().ToArray());
}
}
class Program
{
static void Main()
{
string example = "Hello";
Console.WriteLine(example.ReverseString());
}
}
空合并运算符 ??
用于简化空值检查。
string name = null;
string displayName = name ?? "Unknown";
Console.WriteLine(displayName); // Output: Unknown
空条件运算符 ?.
避免空引用异常,简化对空值的访问操作。
Person person = null;
Console.WriteLine(person?.Name ?? "Name is null");
C# 7 引入了元组解构,允许你从函数中返回多个值并解构它们。
(string name, int age) GetPersonInfo()
{
return ("Alice", 30);
}
class Program
{
static void Main()
{
var (name, age) = GetPersonInfo();
Console.WriteLine($"Name: {name}, Age: {age}");
}
}
模式匹配用于简化类型判断和条件分支。
object obj = 42;
if (obj is int num)
{
Console.WriteLine($"Integer: {num}");
}
void CheckType(object o)
{
switch (o)
{
case int i:
Console.WriteLine($"Integer: {i}");
break;
case string s:
Console.WriteLine($"String: {s}");
break;
default:
Console.WriteLine("Unknown type");
break;
}
}
CheckType(42);
CheckType("Hello");
表达式体成员让方法、属性的定义更简洁,尤其适合简单的操作。
public class Person
{
public string Name { get; }
public Person(string name) => Name = name;
public string GetName() => Name;
}
C# 8 引入了可空引用类型,增强了对空引用的静态分析,减少 NullReferenceException
的可能性。
#nullable enable
public class Person
{
public string? Name { get; set; } // 允许为空的引用类型
}
class Program
{
static void Main()
{
Person person = new Person();
Console.WriteLine(person.Name?.ToUpper() ?? "Name is null");
}
}
协变和逆变允许泛型接口、委托在某些场景下以更宽泛的类型处理。
// 协变允许从派生类向基类转换
IEnumerable<object> objs = new List<string>();
// 逆变允许从基类向派生类转换
Action<object> actObj = obj => Console.WriteLine(obj);
Action<string> actStr = actObj;
actStr("Hello");
dynamic
关键字允许在运行时决定对象的类型,可以避免编译时检查。
dynamic obj = 10;
Console.WriteLine(obj.GetType()); // Output: System.Int32
obj = "Hello";
Console.WriteLine(obj.GetType()); // Output: System.String
反射允许在运行时获取类型的元数据和动态调用方法。
var type = typeof(Person);
var properties = type.GetProperties();
foreach (var prop in properties)
{
Console.WriteLine($"Property: {prop.Name}, Type: {prop.PropertyType}");
}
var person = Activator.CreateInstance<Person>();
var nameProp = type.GetProperty("Name");
nameProp?.SetValue(person, "John");
Console.WriteLine(person.Name);
这些高级用法展示了 C# 语言的灵活性与强大特性,掌握这些工具和技巧将使你的代码更加简洁、灵活,并且更具维护性。这些示例覆盖了 C# 的各个方面,帮助你在实际开发中提高效率并编写出高质量的代码。