白癜风哪里治疗的最好 http://pf.39.net/bdfyy/bjzkbdfyy/190321/6983144.htmlC#中的9个“黑魔法”与“骚操作”
我们知道C#是非常先进的语言,因为是它很有远见的“语法糖”。这些“语法糖”有时过于好用,导致有人觉得它是C#编译器写死的东西,没有道理可讲的——有点像“黑魔法”。
那么我们可以看看C#这些高级语言功能,是编译器写死的东西(“黑魔法”),还是可以扩展(骚操作)的“鸭子类型”。
我先列一个目录,大家可以对着这个目录试着下判断,说说是“黑魔法”(编译器写死),还是“鸭子类型”(可以自定义“骚操作”):
LINQ操作,与IEnumerableT类型;
async/await,与Task/ValueTask类型;
表达式树,与ExpressionT类型;
插值字符串,与FormattableString类型;
yieldreturn,与IEnumerableT类型;
foreach循环,与IEnumerableT类型;
using关键字,与IDisposable接口;
T?,与NullableT类型;
任意类型的Index/Range泛型操作。
1.LINQ操作,与IEnumerableT类型
不是“黑魔法”,是“鸭子类型”。
LINQ是C#3.0发布的新功能,可以非常便利地操作数据。现在12年过去了,虽然有些功能有待增强,但相比其它语言还是方便许多。
如我上一篇博客提到,LINQ不一定要基于IEnumerableT,只需定定义一个类型,实现所需要的LINQ表达式即可,LINQ的select关键字,会调用.Select方法,可以用如下的“骚操作”,实现“移花接木”的效果:
voidMain()
{
varquery=
fromiinnewF()
select3;
Console.WriteLine(string.Join(",",query));//0,1,2,3,4
}
classF
{
publicIEnumerableintSelectR(Funcint,Rt)
{
for(vari=0;i5;++i)
{
yieldreturni;
}
}
}
2.async/await,与Task/ValueTask类型
不是“黑魔法”,是“鸭子类型”。
async/await发布于C#5.0,可以非常便利地做异步编程,其本质是状态机。
async/await的本质是会寻找类型下一个名字叫GetAwaiter()的接口,该接口必须返回一个继承于INotifyCompletion或ICriticalNotifyCompletion的类,该类还需要实现GetResult()方法和IsComplete属性。
这一点在C#语言规范中有说明,调用awaitt本质会按如下顺序执行:
先调用t.GetAwaiter()方法,取得等待器a;
调用a.IsCompleted取得布尔类型b;
如果b=true,则立即执行a.GetResult(),取得运行结果;
如果b=false,则看情况:
如果a没实现ICriticalNotifyCompletion,则执行(aasINotifyCompletion).OnCompleted(action)
如果a实现了ICriticalNotifyCompletion,则执行(aasICriticalNotifyCompletion).OnCompleted(action)
执行随后暂停,OnCompleted完成后重新回到状态机;
有兴趣的可以访问Github具体规范说明: