C#的隐藏特性

C#的隐藏特性

技术背景

C# 作为一种广泛使用的面向对象编程语言,具有许多强大的特性。然而,其中一些特性并未被开发者充分了解和利用。这些隐藏特性可以帮助开发者编写更简洁、高效和易维护的代码。

实现步骤

1. 使用 System.IO.Path.Combine()

System.IO.Path.Combine() 方法用于将多个路径组合成一个路径,避免手动拼接路径时可能出现的错误。

1
2
3
string dir = "C:\\MyDirectory";
string fileName = "myfile.txt";
string path = System.IO.Path.Combine(dir, fileName);

2. 利用 Lambda 表达式和类型推断

Lambda 表达式可以简化代码,并且可以自动转换为兼容的委托对象。同时,类型推断可以减少代码中的类型声明。

1
2
3
4
Console.CancelKeyPress += (sender, e) => {
Console.WriteLine("CTRL+C detected!\n");
e.Cancel = true;
};

3. 使用空合并运算符 ??

空合并运算符用于在对象为 null 时提供默认值。

1
2
3
string value1 = null;
string value2 = "default";
string result = value1 ?? value2;

4. 别名泛型

使用 using 关键字为复杂的泛型类型创建别名,提高代码的可读性。

1
using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;

5. 自动属性不同作用域

自动属性可以设置不同的访问修饰符,如 private set

1
public int MyId { get; private set; }

6. 命名空间别名

为命名空间创建别名,避免命名冲突。

1
2
3
4
5
using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;

web::Control aWebControl = new web::Control();
win::Control aFormControl = new win::Control();

7. as 关键字

as 关键字用于安全地进行类型转换,如果转换失败则返回 null,而不是抛出异常。

1
2
object obj = new object();
MyClass myObject = obj as MyClass;

8. 自动属性和对象初始化器

自动属性可以简化属性的定义,对象初始化器可以简化对象的创建和属性赋值。

1
2
3
public string Name { get; set; }

Employee emp = new Employee { Name = "John Smith", StartDate = DateTime.Now() };

9. default 关键字

在泛型类型中,default 关键字可以根据类型返回默认值。

1
T t = default(T);

10. 表达式树

表达式树可以在运行时表示代码逻辑,结合泛型和 Lambda 表达式可以实现强类型的 API 注册。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MyClass
{
public void SomeMethod() { /* Do Something */ }
}

void RegisterMethod<T>(Expression<Action<T>> action) where T : class
{
var expression = (action.Body as MethodCallExpression);

if (expression != null)
{
// TODO: Register method
Console.WriteLine(expression.Method.Name);
}
}

RegisterMethod<MyClass>(cl => cl.SomeMethod());

11. yield 关键字

yield 关键字用于实现迭代器,允许在迭代过程中逐个返回元素。

1
2
3
4
5
6
public IEnumerable<int> GetNumbers()
{
yield return 1;
yield return 2;
yield return 3;
}

12. 可空类型

可空类型允许基本数据类型具有 null 值。

1
2
double? num1 = null;
double num2 = num1 ?? -100;

13. 匿名类型和方法返回

可以从方法中返回匿名类型,并通过类型推断访问其成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void foo()
{
var user = AnonCast(GetUserTuple(), new { Name = default(string), Badges = default(int) });
Console.WriteLine("Name: {0} Badges: {1}", user.Name, user.Badges);
}

object GetUserTuple()
{
return new { Name = "dp", Badges = 5 };
}

static T AnonCast<T>(object obj, T t)
{
return (T)obj;
}

14. 隐式方法组转换

隐式方法组转换可以简化委托的使用。

1
2
var myStrings = new List<string>() { "abc", "def", "xyz" };
myStrings.ForEach(Console.WriteLine);

核心代码

以下是一些核心代码示例的汇总:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Lambda 表达式
Console.CancelKeyPress += (sender, e) => {
Console.WriteLine("CTRL+C detected!\n");
e.Cancel = true;
};

// 空合并运算符
string result = value1 ?? value2;

// 别名泛型
using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;

// 自动属性
public int MyId { get; private set; }

// as 关键字
MyClass myObject = obj as MyClass;

// 表达式树
RegisterMethod<MyClass>(cl => cl.SomeMethod());

// 可空类型
double? num1 = null;
double num2 = num1 ?? -100;

最佳实践

  • 尽量使用 System.IO.Path.Combine() 来处理路径拼接,避免手动拼接带来的错误。
  • 充分利用 Lambda 表达式和类型推断,使代码更加简洁和易读。
  • 使用空合并运算符 ?? 来处理可能为 null 的对象,提高代码的健壮性。
  • 对于复杂的泛型类型,使用别名泛型来提高代码的可读性。
  • 在类型转换时,优先考虑使用 as 关键字,避免抛出异常。

常见问题

1. as 关键字和强制类型转换的区别

as 关键字在转换失败时返回 null,而强制类型转换在转换失败时会抛出 InvalidCastException 异常。

2. 可空类型的使用场景

可空类型适用于需要表示值不存在的情况,例如数据库查询结果可能为空。

3. 表达式树的性能问题

表达式树在运行时需要进行解析和编译,因此性能相对较低。在性能敏感的场景中,应谨慎使用。


C#的隐藏特性
https://119291.xyz/posts/csharp-hidden-features/
作者
ww
发布于
2025年6月26日
许可协议