C#高级技师语法,你会吗?
【导读】呀,最近太忙了,没什么时间去看和学习,既然长篇文章一时半会吐不出来,短篇还是可以搞搞,操作系统绝不会断更。本文我们来搞点C#中高逼格语法。
=>这玩意从C#6开始支持方法,运算符和只读属性的表达式主体定义。从C#7.0开始支持构造函数,终结器以及属性和索引器访问器的表达式主体定义。所以本文来讲讲=>运算符
高级语法
我们正常写一个方法,都是很明确的方法主体,我们称之为“块主体”,比如如下
static string Say()
{
return "Hello World";
}
用了=>运算符,我们可以将上述方法简化到极致
Console.WriteLine(Say());
static string Say() => "Hello World";
如上就通过=>运算符隐式转换为方法主体的返回类型,最终还是翻译成第一种写法。
C#中的lambda表达式绝对秒杀Java,用过Java我也是这么认为,不服可以一战,我们看用过最多的大概是对集合的处理,集合中内置使用几种委托,继而委托简化为lambda,比如如如下Where过滤条件调用Func委托
var list = new List<string>() { "h", "e", "l", "l", "o" };
list = list.Where(d => d.Equals("o")).ToList();
要是到这里就结束,那么本文也发表不出来,公众号文章必须至少要300字(不算任何标点符号、空格、图片等等),所以我要极力凑满至少300字
开玩笑哈,每写一篇我都竭尽所能希望能让各位童鞋能有所收获,尽管可能每一篇不是那么都尽人意,进入话题正轨
上述只是最基础的铺垫,要是这个语法都不知晓,那这......就不用往下看了,先补补基础知识再继续本文接下来的内容
上述我们讲解了=>运算符和内置泛型委托,我们看到更多的是将委托作为方法参数来使用,将委托作为方法参数或返回值也是可行dei,比如如下:
static Func<long, int> DefaultDelayInSecondsByAttemptFuncOne()
{
return (attempt) =>
{
var random = new Random();
return (int)Math.Round(
Math.Pow(attempt - 1, 4) + 15 + random.Next(30) * attempt);
};
}
定义如上方法后,我们该如何调用呢?你要是会用lambda,那么此种方法调用自然不在话下
var func = DefaultDelayInSecondsByAttemptFuncOne();
Console.WriteLine(func(2));
要是上述方法看不懂,那这.....请折返,那就需要回顾并巩固下基础,这里顺便提一下关于变量定义的问题,有些极力建议不要使用var,比如上述你一眼压根看不出返回类型是啥,只有将鼠标放上去才知道返回的是一个委托,有些用var(比如我)是为了方便,所以这里看个人使用习惯,没有绝对的好与坏
接下来我们再对此方法进行改造,看看该方法的另外一个变体版本
static readonly Func<long, int> DefaultDelayInSecondsByAttemptFuncTwo = attempt =>
{
var random = new Random();
return (int)Math.Round(
Math.Pow(attempt - 1, 4) + 15 + random.Next(30) * attempt);
};
第一眼看起来和第一种定义方式相差无几,我也是这么认为,那么调用该方法和第一种调用是一样的吗?默思一秒,答案:不一样
var result = DefaultDelayInSecondsByAttemptFuncTwo(2);
Console.WriteLine(result);
变体之后的方法调用和我们正常进行方法调用一样,但第一种方式则是返回方法的引用,二者看起来差不多,但是区别还是很大
不知道你注意到了没有,二者还有一个很大的区别,变体方法使用了readonly修饰符,而第一种方式则不能使用该修饰符,是不是又涨知识了呢?
我相信你写过的绝大多数方法都无法使用readonly修饰符(编译报错),所以有面试官问了很偏门的问题,方法支持使用readonly修饰符吗?看过本文后,应毫不犹豫的回答:支持
上述变体方法支持readonly,其本质其实是字段
public static readonly Func<string> Variable1 = () => "Hello";
那么问题来了,有的童鞋就疑惑了,那为什么第一种方式就不支持呢?因为第一种方法返回的是方法引用,这样的答案就好比“标准”解题老师
很显然没有很强的说服力,自问自答,自己骗自己,要是我们如下这样为何就不支持呢?
static readonly string Say() => "Hello World";
至于为何不支持的本质,这个问题就留给大家去探讨吧,至少就目前而言,好像只有上述变体方式支持readonly修饰符,若有深层次见解,欢迎留言
重点来了,又到了,分析本质的时候了
我们看看第一种返回委托的方法大致会翻译成什么呢?别担心,很简单,你看的懂
private static Func<long, int> DefaultDelayInSecondsByAttemptFuncOne()
{
return delegate(long attempt)
{
Random random = new Random();
return (int)Math.Round(Math.Pow(attempt - 1, 4.0) + 15.0 + (double)(random.Next(30) * attempt));
};
}
是不是很了然,就是简单的将委托转换为了匿名方法,但是最终返回的是匿名方法引用,接下来我们再来看第二种方法变体
private static readonly Func<long, int> DefaultDelayInSecondsByAttemptFuncTwo = delegate(long attempt)
{
Random random = new Random();
return (int)Math.Round(Math.Pow(attempt - 1, 4.0) + 15.0 + (double)(random.Next(30) * attempt));
};
该变体则只是将委托转换为匿名方法后将对应参数传进去,但是最后返回的是委托定义的返回值
好了,本文到此结束,接下来继续我们操作系统的学习,我们下一节再见,来自周末凌晨的晚安。
往期推荐
为什么.NET Web 应用推荐使用 await、async异步编程?