我喜欢 C#的理由
1 强类型
2 语法优雅
3 系统内置的库非常全,而且比较规范
4 第三方库可能没有JS,JAVA,PYTHON那么多,但也一般够用
5 可以跨平台
6 默认性能就不错
7 可以利用语法特性写出非常强性能的代码
8 编译速度不错
9 有反射功能
10 有动态的语法
C# 的语法,在我看来,相当的符合人类的直觉,比如
1 前置类型
int a = 1; string name = "Jack";
string Hello(string name){
return "Hello," + name;
}
2 也可以使用类型推断
var a = 1;
var name = "Jack";
List<User> userList = new ();
var userList = new List<User>();
3 字符串插值
var first = "Ma";
var last = "Jack";
var name = $"{first} {last}";
4 字符串可以直接相加.有些语言不是用加号
var name = "Ma" + " " + "Jack";
5 扩展语法.可以直接扩展已有的类(就算是别人写的,第三方的库),最新的版本扩展更强,不过我还没用上.
class MyClass {
public string Name {get;set;}
public MyClass(string name){
this.Name = name;
}
}
static class MyClassExtensition {
public static string GetName(this MyClass myClass){
return this.Name;
}
}
6 属性Property.有机会在访问/更改字段的时候做一些操作,比起 setName,getName 调用起来优雅
class MyClass {
private string name;
public string Name {
get {
Console.Write(name);
return Name;
}
set{
Console.Write(name);
name = value;
}
}
// 自动属性
public int Age { get; set; } = 99;
// 只读属性初始化
public ICollection<int> Values { get; } = new List<int>();
public int Age { get; init; } // 只能在初始化时设置
}
var m = new MyClass();
m.Name = "Ma Jack";
Console.Write(m.Name);
7 Attribute .可以做一些元编程
[ApiController]
[Route("/api/user")]
public class UserController {
[Route("get_name")]
[HttpGet]
public string GetName(){
return "Ma Jack";
}
}
8 linq, expression ,Lambda
var userList = new List<MyClass>();
var filteredList = userList.Where(v=>v.Name.Contains("J"))
.OrderBy(v=>v.Name)
.Select(v=> "Hello," + v.Name)
.Take(10)
.ToList();
var results = from p in people
where p.Age > 18
orderby p.Name
select p.Name;
9 disposable 模式,释放资源比较优雅
class Db : IDioposable {
private Connection connection;
public Db(){
connection = new Connection();
}
public List QueryList(string sql){
//....
}
public Task<List> QueryListAsync(string sql){
//....
}
public void Dispose(){
connection.Close();
}
}
//调用DB类访问数据并自动关闭数据库连接,即使中间有出现异常
using var db = new Db();
var userList = db.QueryList("select * from sys_user");
//--这里自动调用 db.Dispose();
10 async/await
//调用DB类访问数据并自动关闭数据库连接,即使中间有出现异常
using var db = new Db();
var userList = await db.QueryListAsync("select * from sys_user");
//--这里自动调用 db.Dispose();
11 修饰
public
private
protected
readonly
static
...
12 静态类和静态构造
static class Tools {
static string NewMd5(){
return ...;
}
}
class class User {
static List<User> cachedUserList = new ();
//静态构造
static User(){
cachedUserList = GetUserListFromDatabase();
}
}
// 模块级初始化
[ModuleInitializer]
internal static void Initialize()
{
// 模块加载时自动执行
}
13 模式匹配 (C# 7.0+)
// 类型模式
if (obj is string s)
{
Console.WriteLine(s.Length);
}
// 常量
if (count is 0)
{
Console.WriteLine("Empty");
}
// Switch 表达式
var result = shape switch
{
Circle c => $"Circle with radius {c.Radius}",
Rectangle r => $"Rectangle {r.Width}x{r.Height}",
_ => "Unknown shape"
};
//递归
if (person is { Address: { City: "New York" } })
{
Console.WriteLine("New Yorker");
}
14 元组和解构
(int x,int y) GetCoordinates(){
return (100,200);
}
// 元组解构
var (x, y) = GetCoordinates();
var (_, _, area) = GetShapeInfo(); // 忽略前两个返回值
15 字符串定义
var str = "1";
var str = @"1";
var str = $"now : {DateTime.Now}";
var json = """
{
"name": "John",
"age": 30
}
""";
16 空条件运算符 (?. 和 ?[])
Customer? customer = GetCustomer();
var length = customer?.Orders?[0]?.Description?.Length;
// 空合并运算符
var name = customer?.Name ?? "Unknown";
// 空合并赋值 (C# 8.0+)
list ??= new List<int>();
17 结构类型.高效
struct Point {
public int X {get;set;}
public int Y {get;set;}
}
18 记录类型 (C# 9.0+)
public record Person(string FirstName, string LastName);
//clone
var newPerson = person with { LastName = "Smith" };
if (person is not null and { Age: >= 18 })
{
// ...
}
// 不可变且自带值语义比较
var person1 = new Person("John", "Doe");
var person2 = person1 with { LastName = "Smith" };
19 索引与范围 (C# 8.0+)
var lastItem = array[^1]; // 最后一个元素
var slice = array[1..4]; // 从索引1到3的元素
20 命名参数与可选参数
public void Configure(int width, int height = 600, string title = "App")
{
// ...
}
// 调用
Configure(width: 800, title: "My Application");
21 重载
public class MyClass {
private string name {get;set;}
public MyClass(){
this.name = "---";
}
public MyClass(string name){
this.name = name;
}
public string Hello(){
return "Hello," + name;
}
public string Hello(string s){
return s + name;
}
}
22 集合初始化
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var dict = new Dictionary<int, string>
{
[1] = "One",
[2] = "Two"
};
23 操作符可重载
24 局部函数
public int Factorial(int n)
{
return Compute(n);
int Compute(int k) => k <= 1 ? 1 : k * Compute(k - 1);
}
25 表达式成员
public override string ToString() => $"{FirstName} {LastName}";
public double Area => Width * Height;
26 nameof 表达式
Console.WriteLine(nameof(Person.Name)); // 输出 "Name"
27 调用方信息特性
void Log([CallerMemberName] string member = "",
[CallerFilePath] string file = "",
[CallerLineNumber] int line = 0)
{
Console.WriteLine($"{file}:{line} in {member}");
}
28 分部类.可以将一个类文件,拆分成几个文件,可以达到
1) 将大类按功能拆分成多个文件,更好维护
2) 可以一部分是自动代码生成的,另一个部分是手动修改的,这样即可以利用机器自动产生代码,然后又可以定制这个产生的代码