温故之C# 便捷语法二

本文包含以下便捷语法:

  • out 变量
  • 元组
  • 占位符
  • is 模式表达式
  • switch 模式表达式
  • 本地函数
  • 二进制表示和数字分隔符

out 变量

以前,需要将 out 变量的声明、使用为两个不同的语句,如下所示:

int numericResult;
if (int.TryParse(input, out numericResult))
    WriteLine(numericResult);
else
    WriteLine("Could not parse input");

现在,可将前面两行合并为一行表示:

if (int.TryParse(input, out int result))
    WriteLine(result);
else
    WriteLine("Could not parse input");

虽然只比之前简洁了一点点,但,有总比没有好吧~

元组

元组是包含多个字段以表示数据成员的轻量级数据结构。
元组在作为 privateinternal 方法的返回类型时是最有用的,元组为这些方法提供了简单的语法以返回多个离散值,不用再费心定义返回类型的 classstruct
其注意事项如下:

新的元组功能需要 ValueTuple 类型。 为在不包括该类型的平台上使用它,必须添加 NuGetSystem.ValueTuple

通过为每个成员赋值,可以创建一个元组, 此赋值会创建其成员为 Item1Item2 的元祖,其使用方式与 Tuple 的相同。:

var letters = ("a", "b");

可更改语法,以创建为每个元组成员提供语义名称的元组,以下namedLetters 元组包含称为 AlphaBeta 的字段。:

// 方式一
(string Alpha, string Beta) namedLetters = ("a", "b");
// 方式二
var namedLetters = (Alpha: "a", Beta: "b");

当用于方法的返回值时,使用方式如下(在一个整数序列中找到的最小值和最大值):

public (int Max, int Min) Range(IEnumerable<int> numbers) {
  int min = int.MaxValue;
  int max = int.MinValue;
  foreach (var n in numbers) {
    min = (n < min) ? n : min;
    max = (n > max) ? n : max;
  }
  return (max, min);
}

看,这种方式是不是比以前更方便

放在以前,为了让返回值包含最大值和最小值,还需要创建一个类或结构体;当然,在返回值个数比较少时,依然可以使用 refout 来实现多个值的返回

占位符

方法返回值中的占位

占位符相当于未赋值的变量,它们没有值。被放弃的变量将不为该变量分配存储空间,所以弃元可减少内存分配。
使用场景:假定有如下函数(该函数在一个单独的不可更改的程序集中),该函数用于获取具体位置:

public (string Province, string City, string Address) GetLocation() {
  return ("Sichuang", "Chengdu", "Hi-Tech Zone");
}

现我们只需要获取城市,而不需要省份与具体地址,则可以以如下方式调用:

var (_, city, _) = GetLocation();

这样有个好处,可以节省内存,因为系统将不会为 ProvinceCity 分配内存。

out 参数中的占位

使用场景:比如我们需要验证用户输入的手机号是否为三大运营商发行的号段,以前是这样的:

string phoneNumber;
if (Utils.ParsePhoneNumber(phoneNumberStr, out phoneNumber)) {
  Console.WriteLine("This is a phone number");
} else {
  Console.WriteLine("Not a phone number");
}

现在我们可以这样写,除了语法更加简洁,还可以稍微节约点内存(因为我们此处并不需要解析后的号码,这个用户已经输入了,我们仅需要判断是否符合条件即可):

if (Utils.ParsePhoneNumber(phoneNumberStr, out _)) {
  Console.WriteLine("This is a phone number");
} else {
  Console.WriteLine("Not a phone number");
}

is 模式表达式

is 模式表达式扩展了常用 is 运算符,使其可查询其类型之外的对象。它可以在检查类型过程中编写变量初始化。

object obj = "value";
if (obj is string tmp) {
    Console.WriteLine($"obj is a string, value is {tmp}");
}

这部分的意思是,如果 objstring 类型的实例,则分配临时变量 tmp 来保存转换为 string 之后的值。

switch 模式表达式

看代码即可,具体意义同 is 模式表达式:

public static int DiceSum4(IEnumerable<object> values) {
    var sum = 0;
    foreach (var item in values) {
        switch (item) {
            case 0:
                break;
            case int val:
                sum += val;
                break;
            case IEnumerable<object> subList when subList.Any():
                sum += DiceSum4(subList);
                break;
            case IEnumerable<object> subList:
                break;
            case null:
                break;
            default:
                throw new InvalidOperationException("unknown item type");
        }
    }
    return sum;
}

本地函数

使用场景:当某一函数 A 需要通过另一个函数 B 来进行更加复杂的处理,但其他地方都不会用到 B,此时,我们可以将 B 声明在 A 的内部,示例如下:

public static IEnumerable<char> AlphabetSubset3(char start, char end) {
    if (start < 'a' || start > 'z')
        throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter");
    if (end < 'a' || end > 'z')
        throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter");

    if (end <= start)
        throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}");

    return alphabetSubsetImplementation();

    IEnumerable<char> alphabetSubsetImplementation() {
        for (var c = start; c < end; c++)
            yield return c;
    }
}

本地方法仅在外部方法的上下文中引用。本地函数的规则还确保开发人员不会意外地从类中的另一个位置调用本地函数和绕过参数验证。

二进制表示和数字分隔符

在创建位掩码时,或每当数字的二进制表示形式使代码最具可读性时, 可使用二进制进行表示,常量开头的 0b 表示该数字以二进制数形式写入。示例如下:

public const int One =  0b0001;
public const int Two =  0b0010;
public const int Four = 0b0100;
public const int Eight = 0b1000;

如果二进制很长,可通过 _ 作为数字分隔符通常更易于查看,如下:

public const int Sixteen =   0b0001_0000;
public const int ThirtyTwo = 0b0010_0000;
public const int SixtyFour = 0b0100_0000;
public const int OneHundredTwentyEight = 0b1000_0000;

数字分隔符可以出现在常量的任何位置:

// 对于十进制数字,通常将其用作千位分隔符
public const long BillionsAndBillions = 100_000_000_000;
// 数字分隔符也可以与 decimal、float 和 double 类型一起使用
public const double AvogadroConstant = 6.022_140_857_747_474e23;
public const decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;

这样,可读性就很强了。

至此,本节内容讲解完毕。欢迎关注公众号【嘿嘿的学习日记】,所有的文章,都会在公众号首发;或加个人微信【JameLee6292】共同探讨。谢谢您咯~

公众号二维码如下:

公众号二维码
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容