C#高级技师语法,你会吗?

共 3165字,需浏览 7分钟

 ·

2020-08-01 06:03




【导读】呀,最近太忙了,没什么时间去看和学习,既然长篇文章一时半会吐不出来,短篇还是可以搞搞,操作系统绝不会断更。本文我们来搞点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<longintDefaultDelayInSecondsByAttemptFuncOne()
{
 return (attempt) =>
 {
  var random = new Random();
  return (int)Math.Round(
   Math.Pow(attempt - 14) + 15 + random.Next(30) * attempt);
 };
}

定义如上方法后,我们该如何调用呢?你要是会用lambda,那么此种方法调用自然不在话下

var func = DefaultDelayInSecondsByAttemptFuncOne();
Console.WriteLine(func(2));

要是上述方法看不懂,那这.....请折返,那就需要回顾并巩固下基础,这里顺便提一下关于变量定义的问题,有些极力建议不要使用var,比如上述你一眼压根看不出返回类型是啥,只有将鼠标放上去才知道返回的是一个委托,有些用var(比如我)是为了方便,所以这里看个人使用习惯,没有绝对的好与坏


接下来我们再对此方法进行改造,看看该方法的另外一个变体版本

static readonly Func<longint> DefaultDelayInSecondsByAttemptFuncTwo = attempt =>
{
 var random = new Random();
 return (int)Math.Round(
  Math.Pow(attempt - 14) + 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<longintDefaultDelayInSecondsByAttemptFuncOne()
{
 return delegate(long attempt)
 {
  Random random = new Random();
  return (int)Math.Round(Math.Pow(attempt - 14.0) + 15.0 + (double)(random.Next(30) * attempt));
 };
}


是不是很了然,就是简单的将委托转换为了匿名方法,但是最终返回的是匿名方法引用,接下来我们再来看第二种方法变体

private static readonly Func<longint> DefaultDelayInSecondsByAttemptFuncTwo = delegate(long attempt)
{
 Random random = new Random();
 return (int)Math.Round(Math.Pow(attempt - 14.0) + 15.0 + (double)(random.Next(30) * attempt));
};

该变体则只是将委托转换为匿名方法后将对应参数传进去,但是最后返回的是委托定义的返回值


好了,本文到此结束,接下来继续我们操作系统的学习,我们下一节再见,来自周末凌晨的晚安。

往期推荐

最全C#自学资源汇总

卧槽,Chrome神器插件!

雷军 1994 年写的代码,经典老古董~

某程序员动了公司的祖传代码“屎山”,半年后怒交辞职报告!

为什么.NET Web 应用推荐使用 await、async异步编程?

回复 【关闭】广
回复 【实战】获取20套实战源码
回复 【福利】获取最新微信支付有奖励
回复 【被删】
回复 【访客】访
回复 【卡通】学制作微信卡通头像
回复 【python】学微获取全套0基础Python知识手册
回复 【2019】获取2019 .NET 开发者峰会资料PPT
浏览 14
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报