enum AccountType {Trial,Basic,Pro}
record Account(string Id, AccountType Type, string Name);
interface IDatabase<T> {Task Insert(T item);Task<T> Get(stringid);}
class AccountManager {
publicAccountManager(IDatabase<Account> database) {_database = database;}
public async voidCreateAccount(AccountType type, string name) {try {var account = newAccount(Guid.NewGuid.ToString,type,name);await_database.Insert(account)} catch (Exceptionexception) {Console.WriteLine($"An unexpected error occurred while creating anaccount. Name: {name}, Exception: {exception}");}}
IDatabase<Account>_database;}
C#类的示例
C#的其他优势
与Type相似并不是C#的唯一优点,它还有其他优点:
与原生代码结合C#的最大优势之一就是它可以深入原生代码。本文开头提到,Type并不擅长与C/C++代码结合。Node.js有一个支持原生C/C++的插件,名为Node-API,但是它需要为原生函数编写额外的C++包裹器,将原生类型转换成Java对象,或相反,类似于JNI的工作方式。而C#可以直接调用原生函数,只需把库放到应用程序的bin目录下,然后将API定义为C#中的外部函数即可。然后就能像C#函数一样使用外部函数,.NET运行时会处理好C#数据类型与原生数据类型之间的转换。例如,如果原生库导出了下面的C函数:
int countOccurrencesOfCharacter(char *string, char character) {int count = 0;for (int i = 0;string[i] != '\0'; i++) {if (string[i] ==character) {count++;}}return count;}那么可像下面这样从C#中调用:
using System;using System.Runtime.InteropServices;var count = MyLib.countOccurrencesOfCharacter("C# is prettyneat, eh?", 'e');// Prints "3"Console.WriteLine(count);
class MyLib {// Just placeMyLibraryName.so in the app's bin folder[DllImport("MyLibraryName")]public static externint countOccurrencesOfCharacter(string str, char character);}
这种方法可以通过C连接访问任何动态库(.so、.dll或.dylib),也就是说,你可以轻松地调用C、C++、Rust、Go或其他语言编写的代码,只要编译成机器码即可。原生交互的其他应用还有:
事件C#的一个独特的特性是,提供了一流的事件支持。在Type中,你可以实现addEventListener方法,让客户端监听事件,而C#有event关键字,可以用来定义事件,并通过简单的语法将事件通知给所有监听者(而不需要像Type那样手动遍历所有事件监听者并在try/catch块中执行)。例如,我们可以让Connection类定义一个MessageReceived事件,如下所示:
class Connection {// AnAction<string> is a callback that accepts a string parameter.public eventAction<string> MessageReceived;}使用Connection代码可以通过+=操作符给MessageReceived添加一个处理函数,如下:
var connection = new Connection;connection.MessageReceived += (message) => {Console.WriteLine("Message was received: " + message);};而Connection类可以在内部调用MessageReceived,为所有监听者触发MessageReceived事件:
// Raise the MessageReceived eventMessageReceived?.Invoke(message);其他优势
性能:C#很快。C#的ASP.NET Web框架一直在Techempower的评测中名列前茅,而C#的.NET CoreCLR运行时的性能每个主要版本都在提高。C#拥有优良性能的原因之一是,通过使用结构而不是类,应用程序可以最小化甚至完全消除垃圾回收。因此,C#在视频游戏编程中非常流行。
游戏和混合现实:C#是游戏开发最流行的语言之一,像Unity、Godot甚至Unreal游戏引擎都使用了C#。C#在混合现实中也很流行,因为VR和AR应用程序都是用Unity编写的。
由于C#拥有第一方库、工具和文档,因此一些任务非常容易实现,比如,在C#中创建gRPC客户端要比Type方便得多。相反,在Node.js中使用Type时,就必须找出正确的模块和工具的组合,才能正确地生成Java gRPC客户端,以及相应的Type类型。
高级功能:C#有许多其他语言没有的功能,如运算符重载、析构函数等。
总结
如前所述,世上没有完美的语言。在设计语言时总要有所权衡,所以一些语言的速度更快,但使用难度会增加(例如Rust的借出检查)。另一方面,一些语言非常易用,但通常性能的优化难度就会增加(例如Java的动态语言特性)。正因如此,我相信掌握一组相似的语言会非常有用:这些语言分别有各自的长处,但都很相似,而且能互相配合。例如,下面是我选择的一组语言:
Type
- 最高层的语言,开发速度最快
- 性能并非最佳,但适用于大多数应用
- 不太适合与原生代码结合
C#
- 仍然是高级语言,支持垃圾回收,所以很容易使用,尽管并不如Type那么容易。
- 从速度和内存占用量来看,其性能都优于 Type
- 最重要的是,能够与底层很好地结合
C++
- 开发难度较大(例如需要手动内存管理),因此开发速度会慢很多
- 但运行时的性能最佳!而且随处可用,能与许多已有的软件相结合
- 很像C#,而且标准库很好,但也有许多陷阱(大多数与内存管理有关)。我更希望使用Rust,因为它的内存安全性更好,但我的许多工作都要与已有的C++代码结合,因此使用C++会更容易 。
参考链接:https://nate.org/csharp-and-type
☞ 34 年了,“杀”不死的 Perl!
☞ 第一台计算机背后的女性们;Box创始人出生;开普勒诞生|历史上的今天
☞腾讯企业QQ将停运;雷军:小米汽车预计2024年量产;iPhone或将取消SIM卡槽,全部改用eSIM卡|极客头条 返回搜狐,查看更多