C# 中 System.Index 结构体和 Hat 运算符(^)的使用示例

翻译自 John Demetriou 2019年2月17日 的文章 《C# 8 – Introducing Index Struct And A Brand New Usage For The Hat Operator》

今天我们要讲的是 Hat 运算符(^)。目前为止,Hat 运算符(^)已经被用作布尔类型的异或运算符,以及字节、整型类型的按位异或运算符。在 C# 8 中,它有一个新的用法。

这个运算符的新用法是自动创建 Index 结构体的实例。那什么是 Index 结构呢?这在 C# 8 中也有介绍。
Index 结构体的代码(就像所有的 C# 代码一样)可以在github 上找到。你可以看到,它是一个相当简单的结构体,包含一个整数值,和一个定义是否应该从末尾开始计数的布尔值。
它有助于让访问数组比以往容易很多。我们可以很轻松地将这个值存储在一个 Index 类型中来代替一个整数,它比一个简单的整数更清楚地定义了我们的意图,并有助于避免该变量的误用。

到目前为止,当尝试访问数组中特定索引处的值时,我们总是从第一个元素开始考虑。那么 Hat 运算符(^)是如何帮助我们的呢?例如,如果你想获取一个已知大小的数组的最后一个的元素,你通常会从数组的 Length 中减去 1,并在检索时使用这个技巧或硬编码的数字。

例如:

int[] array = new int[] { 1, 3, 5, 7, 9 };
var x = array[4];

你可以像下面的例子一样使用数组提供的变量:

int[] array = new int[] { 1, 3, 5, 7, 9 };
var x = array[array.Length - 1];

这种方法也可以用于编译时长度未知的数组。并且这通常是首选方法,因为它表明您希望更容易地检索最后一项,而不是必须进行计数来查看哪个是第四项并验证它是最后一项。

适当的使用 Index 结构,我们可以很容易地创建一个索引值类型,这样我们就可以存储它并随心地重用它,以避免违反 DRY 原则。

Index lastItem = new Index(4, false);
int[] array = new int[] { 1, 3, 5, 7, 9 };
var x = array[lastItem];

译者注:
DRY 是 “Don't repeat yourself” 的缩写,是软件开发的一个原则,旨在减少软件模式的重复,用抽象来替代它,或者使用数据规范化来避免冗余。也就是说,在一个设计里,对于任何东西,都应该有且只有一个表示,其它的地方都应该引用这一处。这样需要改动的时候,只需调整这一处,所有的地方就都变更过来了。

但正如我们所看到的,我们还可以使用 fromEnd 参数来更好地表达我们希望检索最后一项,并在编译时从一个大小未知的数组中检索最后一项。

Index lastItem = new Index(1, true);
int[] array = new int[] { 1, 3, 5, 7, 9 };
var x = array[lastItem];

不过,我们需要记住的一点是,当从末尾开始计数时,不是以 0 开始的索引。把它想象成我们使用的 Length - x ,其中 x 就是我们在 Index 结构体构造函数中使用的值。

但是 Hat 运算符(^)在这一切中有何用武之地呢?唔,Hat 运算符(^) 是调用 Index 结构体时将 fromEnd 设置为 true 的简写方式。 比如,下面的两行是完全相同的:

Index lastItem = new Index(1, true); // line 1
int[] array = new int[] { 1, 3, 5, 7, 9 };
var x = array[lastItem];

Index lastItem = ^1; //line 2, 同 line 1
int[] array = new int[] { 1, 3, 5, 7, 9 };
var x = array[lastItem];

或者,如果你想要检索倒数第二项,你可以这么做:

Index secondToLast = new Index(2, true);
int[] array = new int[] { 1, 3, 5, 7, 9 };
var x = array[secondToLast];

Index secondToLast = ^2;
int[] array = new int[] { 1, 3, 5, 7, 9 };
var x = array[secondToLast];

就这样,一个新的结构体类型和一个旧运算符(^)的新用法打包在一起了。

作者 : John Demetriou
译者 : 技术译民
出品 : 技术译站
链接 : 英文原文

以上就是C# 中 System.Index 结构体和 Hat 运算符(^)的使用示例的详细内容,更多关于C# 中 System.Index 结构体和 Hat 运算符的资料请关注我们其它相关文章!

(0)

相关推荐

  • 快速了解c# 结构体

    C# 结构体 在 C# 中,结构体是值类型数据结构.它使得一个单一变量可以存储各种数据类型的相关数据.struct 关键字用于创建结构体. 定义结构体 struct Books { public string title; public string author; public string subject; public int book_id; }; 结构的用法 public class testStructure { public static void Main(string[] ar

  • 详解C# 结构体

    在 C# 中,结构体是值类型数据结构.它使得一个单一变量可以存储各种数据类型的相关数据.struct 关键字用于创建结构体. 结构体是用来代表一个记录.假设您想跟踪图书馆中书的动态.您可能想跟踪每本书的以下属性: Title Author Subject Book ID 定义结构体 为了定义一个结构体,您必须使用 struct 语句.struct 语句为程序定义了一个带有多个成员的新的数据类型. 例如,您可以按照如下的方式声明 Book 结构: struct Books { public str

  • C#中的==运算符

    在这篇文章中,我们将介绍如下内容: ==运算符与基元类型 ==运算符与引用类型 ==运算符与String类型 ==运算符与值类型 ==运算符与泛型 ==运算符与基元类型 我们分别用两种方式比较两个整数,第一个使用的是Equals(int)方法,每二个使用的是==运算符: class Program { static void Main(String[] args) { int num1 = 5; int num2 = 5; Console.WriteLine(num1.Equals(num2))

  • C# 7.2中结构体性能问题的解决方案

    前言 在某些使用了readonly关键字的情况下,C#编译器会创建出结构体的防御副本.虽然这个问题已经众所周知并被记录下来了,但仍然值得重新审视,因为它与C# 7.2的几个特性有关.in和ref readonly关键字的使用让这个问题出现得更频繁,而readonly结构体提供了一种解决方法. C#中的结构体通常用于提升性能,减少用于分配和销毁内存的开销.然而,潜在的陷阱限制了它们的使用.C# 7.2增加了一个改进的readonly结构体来解决这个问题. 在如下几种情况下,C#编译器将为结构体创建

  • 关于C#结构体 你需要知道的

    结构体概念 在C#中,结构体是值类型,一般适用于表示类似Point.Rectangle.Color的对象 值类型能够降低对堆的管理.使用.降低垃圾回收,表现出更好的性能.可是值类型也有不好的一面.会涉及到装箱拆箱等操作 结构体声明 结构体声明定义了一种新的数据类型,这个数据类型可以为程序包含一个以上的成员变量 要定义一个结构,需要使用struct语句 声明一个学校的结构 struct School { public int name; public string head_master; pub

  • C# DataTable中Compute方法用法集锦(数值/字符串/运算符/表等操作)

    本文实例讲述了C# DataTable中Compute方法用法.分享给大家供大家参考,具体如下: Compute函数的参数就两个:Expression,和Filter. Expresstion是计算表达式,关于Expression的详细内容请看这里: http://msdn2.microsoft.com/zh-cn/library/system.data.datacolumn.expression(VS.80).aspx 而Filter则是条件过滤器,类似sql的Where条件. DataTab

  • 浅析C# 结构体struct

    结构体 有时候我们仅需要一个小的数据结构,类提供的功能多于我们需要的功能:考虑到性能原因,最好使用结构体. 结构体是值类型,存储在栈中或存储为内联(如果结构体是存储在堆中的另一个对象的一部分). 例如类class: public class Dimensions { public Dimensions(double length, double width) { Length = length; Width = width; } public double Length { get; set;

  • C#6 null 条件运算符

    1. 老版本的代码 namespace csharp6 { internal class Person { public string Name { get; set; } } internal class Program { private static void Main() { Person person = null; string name = null; if (person != null) { name = person.Name; } } } } 在我们使用一个对象的属性的时候

  • C#中常用的运算符总结

    在C#中常用到的运算符有条件运算符,is运算符,as运算符,typeof 运算符等等,接下来在文章中将为大家具体介绍各个运算符的使用方法 条件运算符 条件运算符用( ?: )来表示 condition ? X:Y 上述的语句表示的是如果条件为真 ? 则为 X : 否则为 Y 条件运算符可以称为三元运算符,是if..else 的简化形式.首先先判断一个条件,如果条件为真,返回第一个值,否则返回第二个值.恰当 的使用三元运算符可以使程序更加简洁. as运算符 as运算符表示的是强制转换,即便是转换失

  • 详细分析c# 运算符重载

    您可以重定义或重载 C# 中内置的运算符.因此,程序员也可以使用用户自定义类型的运算符.重载运算符是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的.与其他函数一样,重载运算符有返回类型和参数列表. 例如,请看下面的函数: public static Box operator+ (Box b, Box c) { Box box = new Box(); box.length = b.length + c.length; box.breadth = b.breadth

随机推荐