我喜欢 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) 可以一部分是自动代码生成的,另一个部分是手动修改的,这样即可以利用机器自动产生代码,然后又可以定制这个产生的代码


标签: none