C#教程5:操作算子(2)
十、C# 复合赋值运算符
复合赋值运算符由两个运算符组成。他们是速记运算符。
a = a + 3; a += 3;
+= 复合运算符是这些速记运算符之一。上面两个表达式是相等的。值 3 被添加到 a 变量中。
其他复合运算符有:
-= *= /= %= &= |= <<= >>=
Program.cs
int a = 1; a = a + 1;Console.WriteLine(a);a += 5; Console.WriteLine(a);a *= 3; Console.WriteLine(a);
在示例中,我们使用了两个复合运算符。
int a = 1; a = a + 1;
a 变量初始化为 1。使用非速记符号将 1 添加到变量中。
a += 5;
使用 += 复合运算符,我们将 5 添加到 a 变量。该语句等于 a = a + 5;。
a *= 3;
使用 *= 运算符,a 乘以 3。语句等于 a = a * 3;。
$ dotnet run 2 7 21
十一、C# new操作符
new 运算符用于创建对象和调用构造函数。
Program.cs
var b = new Being(); Console.WriteLine(b);var vals = new int[] { 1, 2, 3, 4, 5 }; Console.WriteLine(string.Join(" ", vals));class Being {public Being(){Console.WriteLine("Being created");} }
在示例中,我们使用 new 运算符创建了一个新的自定义对象和一个整数数组。
public Being() {Console.WriteLine("Being created"); }
这是一个构造函数。它在对象创建时被调用。
$ dotnet run Being created Being 1 2 3 4 5
十二、C# 访问运算符
访问运算符 [] 与数组、索引器和属性一起使用。
Program.cs
var vals = new int[] { 2, 4, 6, 8, 10 }; Console.WriteLine(vals[0]);var domains = new Dictionary() {{ "de", "Germany" },{ "sk", "Slovakia" },{ "ru", "Russia" } };Console.WriteLine(domains["de"]);oldMethod();[Obsolete("Don't use OldMethod, use NewMethod instead", false)] void oldMethod() {Console.WriteLine("oldMethod()"); }void newMethod() {Console.WriteLine("newMethod()"); }
在示例中,我们使用 [] 运算符获取数组元素、字典对的值并激活内置属性。
var vals = new int[] { 2, 4, 6, 8, 10 }; Console.WriteLine(vals[0]);
我们定义了一个整数数组。我们使用 vals[0] 获得第一个元素。
var domains = new Dictionary<string, string>() {{ "de", "Germany" },{ "sk", "Slovakia" },{ "ru", "Russia" } };Console.WriteLine(domains["de"]);
创建了一个字典。使用 domains["de"],我们得到具有 "de" 键的对的值。
[Obsolete("Don't use OldMethod, use NewMethod instead", false)] public static void oldMethod() {Console.WriteLine("oldMethod()"); }
我们激活了内置的过时属性。该属性发出警告。
当我们运行程序时,它会产生警告:warning CS0618: 'oldMethod()' is obsolete: 'Don't use OldMethod, use NewMethod instead'。
十三、C# 索引符号 ^
结束运算符 ^ 的索引表示从序列末尾开始的元素位置。例如,^1 指向序列的最后一个元素,^n 指向偏移长度为 n 的元素。
Program.cs
int[] vals = { 1, 2, 3, 4, 5 };Console.WriteLine(vals[^1]); Console.WriteLine(vals[^2]);var word = "gray falcon";Console.WriteLine(word[^1]);
在示例中,我们将运算符应用于数组和字符串。
int[] vals = { 1, 2, 3, 4, 5 };Console.WriteLine(vals[^1]); Console.WriteLine(vals[^2]);
我们打印数组的最后一个元素和最后一个元素。
var word = "gray falcon";Console.WriteLine(word[^1]);
我们打印单词的最后一个字母。
$ dotnet run 5 4 n
十四、C# 范围操作符..
.. 运算符将索引范围的开始和结束指定为其操作数。左边的操作数是一个范围的包含开始。右手操作数是一个范围的唯一结束。
x.. is equivalent to x..^0 ..y is equivalent to 0..y .. is equivalent to 0..^0
.. 运算符的操作数可以省略以获得开放范围。
Program.cs
int[] vals = { 1, 2, 3, 4, 5, 6, 7 };var slice1 = vals[1..4]; Console.WriteLine("[{0}]", string.Join(", ", slice1));var slice2 = vals[..^0]; Console.WriteLine("[{0}]", string.Join(", ", slice2));
在示例中,我们使用 .. 运算符来获取数组切片。
var range1 = vals[1..4]; Console.WriteLine("[{0}]", string.Join(", ", range1));
我们创建一个从索引 1 到索引 4 的数组切片;最后一个索引 4 不包括在内。
var slice2 = vals[..^0]; Console.WriteLine("[{0}]", string.Join(", ", slice2));
在这里,我们基本上创建了数组的副本。
$ dotnet run [2, 3, 4] [1, 2, 3, 4, 5, 6, 7]
十五、C# 类型信息
现在我们关注使用类型的运算符。
sizeof 运算符用于获取值类型的大小(以字节为单位)。 typeof 用于获取类型的 System.Type 对象。
Program.cs
Console.WriteLine(sizeof(int)); Console.WriteLine(sizeof(float)); Console.WriteLine(sizeof(Int32));Console.WriteLine(typeof(int)); Console.WriteLine(typeof(float));
We use the sizeof
and typeof
operators.
$ dotnet run 4 4 4 System.Int32
我们可以看到 int 类型是 System.Int32 的别名,float 是 System.Single 类型的别名。
is 运算符检查对象是否与给定类型兼容。
Program.cs
Base _base = new Base(); Derived derived = new Derived();Console.WriteLine(_base is Base); Console.WriteLine(_base is Object); Console.WriteLine(derived is Base); Console.WriteLine(_base is Derived);class Base { } class Derived : Base { }
我们从用户定义的类型创建两个对象。
class Base {} class Derived : Base {}
我们有一个 Base 和一个 Derived 类。派生类继承自基类。
Console.WriteLine(_base is Base); Console.WriteLine(_base is Object);
Base 等于 Base,因此第一行打印 True。 Base 也与 Object 类型兼容。这是因为每个类都继承自所有类的母亲——Object 类。
Console.WriteLine(derived is Base); Console.WriteLine(_base is Derived);
派生对象与基类兼容,因为它显式继承自基类。另一方面,_base 对象与 Derived 类无关。
$ dotnet run True True True False
as 运算符用于在兼容的引用类型之间执行转换。当无法进行转换时,运算符返回 null。与引发异常的强制转换操作不同。
Program.cs
object[] objects = new object[6]; objects[0] = new Base(); objects[1] = new Derived(); objects[2] = "ZetCode"; objects[3] = 12; objects[4] = 1.4; objects[5] = null;for (int i = 0; i < objects.Length; i++) {string s = objects[i] as string;Console.Write("{0}:", i);if (s != null){Console.WriteLine(s);}else{Console.WriteLine("not a string");} }class Base { } class Derived : Base { }
在上面的示例中,我们使用 as 运算符来执行转换。
string s = objects[i] as string;
我们尝试将各种类型转换为字符串类型。但只有一次铸造有效。
$ dotnet run 0:not a string 1:not a string 2:ZetCode 3:not a string 4:not a string 5:not a string
十六、C# 运算符优先级
运算符优先级告诉我们首先评估哪些运算符。优先级对于避免表达式中的歧义是必要的。
以下表达式的结果是 28 还是 40?
3 + 5 * 5
与数学一样,乘法运算符的优先级高于加法运算符。所以结果是28。
(3 + 5) * 5
要更改或提高优先级,我们可以使用括号。括号内的表达式总是首先被计算。
下表显示了按优先级排序的常见 C# 运算符(最高优先级在前)
Operator(s) | Category | Associativity |
---|---|---|
Primary |
x.y x?.y, x?[y] f(x) a[x] x++ x-- new typeof default checked unchecked
|
Left |
Unary |
+ - ! ~ ++x --x (T)x
|
Left |
Multiplicative |
* / %
|
Left |
Additive |
+ -
|
Left |
Shift |
<< >>
|
Left |
Equality |
== !=
|
Right |
Logical AND |
&
|
Left |
Logical XOR |
^
|
Left |
Logical OR |
|
|
Left |
Conditional AND |
&&
|
Left |
Conditional OR |
||
|
Left |
Null Coalescing |
??
|
Left |
Ternary |
?:
|
Right |
Assignment |
= *= /= %= += -= <<= >>= &= ^= |= ??= =>
|
Right |
表同一行上的运算符具有相同的优先级。
Program.cs
Console.WriteLine(3 + 5 * 5); Console.WriteLine((3 + 5) * 5);Console.WriteLine(! true | true); Console.WriteLine(! (true | true));
在此代码示例中,我们展示了一些表达式。每个表达式的结果取决于优先级。
Console.WriteLine(3 + 5 * 5);
此行打印 28。乘法运算符的优先级高于加法。首先计算 5*5 的乘积,然后加上 3。
Console.WriteLine(! true | true);
在这种情况下,否定运算符具有更高的优先级。首先,第一个真值被否定为假,然后 |运算符将 false 和 true 组合在一起,最终给出 true。
$ dotnet run 28 40 True False
十七、C# 关联规则
有时,优先级不能令人满意地确定表达式的结果。还有另一条规则称为关联性。运算符的关联性决定了具有相同优先级的运算符的评估顺序。
9 / 3 * 3
这个表达式的结果是 9 还是 1?乘法、删除和模运算符从左到右关联。所以表达式是这样计算的:(9 / 3) * 3,结果是 9。
算术、布尔、关系和位运算符都是从左到右关联的。
另一方面,赋值运算符是右关联的。
Program.cs
int a, b, c, d; a = b = c = d = 0;Console.WriteLine("{0} {1} {2} {3}", a, b, c, d);int j = 0; j *= 3 + 1;Console.WriteLine(j);
在示例中,我们有两种情况,其中关联性规则决定了表达式。
int a, b, c, d; a = b = c = d = 0;
赋值运算符是从右到左关联的。如果关联性是从左到右的,则前面的表达式是不可能的。
int j = 0; j *= 3 + 1;
复合赋值运算符是从右到左关联的。我们可能期望结果为 1。但实际结果为 0。因为关联性。首先计算右侧的表达式,然后应用复合赋值运算符。
$ dotnet run 0 0 0 0 0
十八、 C# 空条件运算符
仅当操作数的计算结果为非 null 时,null 条件运算符才会将成员访问、?. 或元素访问、?[] 操作应用于其操作数。如果操作数的计算结果为 null,则应用运算符的结果为 null。
Program.cs
var users = new List<User>() { new User("John Doe", "gardener"), new User(null, null),new User("Lucia Newton", "teacher") };users.ForEach(user => Console.WriteLine(user.Name?.ToUpper()));record User(string? Name, string? Occupation);
在示例中,我们有一个包含两个成员的用户类:姓名和职业。我们在 ? 的帮助下访问对象的名称成员。操作员。
var users = new List<User>() { new User("John Doe", "gardener"), new User(null, null),new User("Lucia Newton", "teacher") };
我们有一个用户列表。其中之一是用空值初始化的。
users.ForEach(user => Console.WriteLine(user.Name?.ToUpper()));
我们使用?。访问 Name 成员并调用 ToUpper 方法。这 ?。通过不对 null 值调用 ToUpper 来防止 System.NullReferenceException。
$ dotnet run JOHN DOELUCIA NEWTON
在以下示例中,我们使用 ?[] 运算符。该运算符允许将空值放入集合中。
Program.cs
int?[] vals = { 1, 2, 3, null, 4, 5 };int i = 0;while (i < vals.Length) {Console.WriteLine(vals[i]?.GetType());i++; }
在此示例中,我们在数组中有一个空值。我们通过应用 ? 来防止 System.NullReferenceException。数组元素上的运算符。
十九、C# 空合并运算符
空合并运算符??用于定义可空类型的默认值。如果它不为空,则返回左操作数;否则返回正确的操作数。当我们使用数据库时,我们经常处理缺失值。这些值作为程序的空值出现。此运算符是处理此类情况的便捷方式。
Program.cs
int? x = null; int? y = null;int z = x ?? y ?? -1;Console.WriteLine(z);
空合并运算符的示例程序。
int? x = null; int? y = null;
两个可为空的 int 类型被初始化为 null。int ?是 Nullable<int> 的简写。它允许将 null 值分配给 int 类型。
int z = x ?? y ?? -1;
我们想为 z 变量赋值。但它不能为空。这是我们的要求。我们可以很容易地为此使用空合并运算符。如果 x 和 y 变量都为空,我们将 -1 分配给 z。
$ dotnet run -1
二十、C# 空合并赋值运算符
仅当左侧操作数的计算结果为 null 时,null 合并赋值运算符 ??= 才将其右侧操作数的值分配给其左侧操作数。如果左侧操作数的计算结果为非空,则??= 运算符不计算其右侧操作数。它在 C# 8.0 及更高版本中可用。
Program.cs
List<int> vals = null;vals ??= new List<int>() {1, 2, 3, 4, 5, 6}; vals.Add(7); vals.Add(8); vals.Add(9);Console.WriteLine(string.Join(", ", vals));vals ??= new List<int>() {1, 2, 3, 4, 5, 6};Console.WriteLine(string.Join(", ", vals));
在示例中,我们对整数值列表使用空合并赋值运算符。
List<int> vals = null;
首先,将列表分配为 null。
vals ??= new List<int>() {1, 2, 3, 4, 5, 6};
我们使用 ??= 为变量分配一个新的列表对象。由于它为 null,因此分配了列表。
vals.Add(7); vals.Add(8); vals.Add(9);Console.WriteLine(string.Join(", ", vals));
我们向列表中添加一些值并打印其内容。
vals ??= new List<int>() {1, 2, 3, 4, 5, 6};
我们尝试为变量分配一个新的列表对象。由于变量不再为空,因此未分配列表。
$ dotnet run 1, 2, 3, 4, 5, 6, 7, 8, 9 1, 2, 3, 4, 5, 6, 7, 8, 9
二十一、C# 三元运算符
三元运算符?: 是一个条件运算符。对于我们想要根据条件表达式选择两个值之一的情况,它是一个方便的运算符。
cond-exp ? exp1 : exp2
如果 cond-exp 为真,则计算 exp1 并返回结果。如果 cond-exp 为假,则计算 exp2 并返回其结果。
Program.cs
int age = 31;bool adult = age >= 18 ? true : false;Console.WriteLine("Adult: {0}", adult);
在大多数国家,成年期取决于您的年龄。如果您超过某个年龄,您就是成年人。这是三元运算符的情况。
bool adult = age >= 18 ? true : false;
首先评估赋值运算符右侧的表达式。三元运算符的第一阶段是条件表达式求值。因此,如果年龄大于或等于 18,则后面的值是?返回字符。如果不是,则返回 : 字符后面的值。然后将返回的值分配给成人变量。
$ dotnet run Adult: True
A 31 years old person is adult.
二十二、C# Lambda操作符号
=> 标记称为 lambda 运算符。它是取自函数式语言的运算符。该运算符可以使代码更短更清晰。另一方面,理解语法可能很棘手。特别是如果程序员以前从未使用过函数式语言。
只要我们可以使用委托,我们也可以使用 lambda 表达式。 lambda 表达式的定义是:lambda 表达式是一个匿名函数,可以包含表达式和语句。左侧是一组数据,右侧是表达式或语句块。这些陈述适用于每一项数据。
在 lambda 表达式中,我们没有 return 关键字。最后一条语句会自动返回。而且我们不需要为我们的参数指定类型。编译器将猜测正确的参数类型。这称为类型推断。
Program.cs
var list = new List<int>() { 3, 2, 1, 8, 6, 4, 7, 9, 5 };var subList = list.FindAll(val => val > 3);foreach (int i in subList) {Console.WriteLine(i); }
我们有一个整数列表。我们打印所有大于 3 的数字。
var list = new List<int>() { 3, 2, 1, 8, 6, 4, 7, 9, 5 };
我们有一个通用的整数列表。
var subList = list.FindAll(val => val > 3);
这里我们使用 lambda 运算符。 FindAll 方法将谓词作为参数。谓词是一种特殊的委托,它返回一个布尔值。谓词适用于列表的所有项目。 val 是一个没有类型指定的输入参数。我们可以显式指定类型,但这不是必需的。
编译器需要一个 int 类型。 val 是列表中的当前输入值。比较它是否大于 3 并返回布尔值 true 或 false。最后,FindAll 将返回满足条件的所有值。它们被分配给子列表集合。
foreach (int i in subList) {Console.WriteLine(i); }
子列表集合的项目被打印到终端。
$ dotnet run 8 6 4 7 9 5
大于 3 的整数列表中的值。
Program.cs
var nums = new List<int>() { 3, 2, 1, 8, 6, 4, 7, 9, 5 };var nums2 = nums.FindAll( delegate(int i) {return i > 3;} );foreach (int i in nums2) {Console.WriteLine(i); }
这是同一个例子。我们使用匿名委托而不是 lambda 表达式。
二十三、C# 计算素数
我们要计算素数。
Program.cs
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 };Console.Write("Prime numbers: ");foreach (int num in nums) {if (num == 1) continue;if (num == 2 || num == 3){Console.Write(num + " ");continue;}int i = (int) Math.Sqrt(num);bool isPrime = true;while (i > 1){if (num % i == 0){isPrime = false;}i--;}if (isPrime){Console.Write(num + " ");} }Console.Write('\n');
在上面的示例中,我们处理了许多不同的运算符。素数(或素数)是一个自然数,它恰好有两个不同的自然数除数:1 和它自己。我们拿起一个数字并将其除以数字,从 1 到拾取的数字。实际上,我们不必尝试所有较小的数字;我们可以除以数字,直到所选数字的平方根。该公式将起作用。我们使用余数除法运算符。
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 };
我们根据这些数字计算素数。
if (num == 1) continue;
By definition, 1 is not a prime
if (num == 2 || num == 3) {Console.Write(num + " ");continue; }
我们跳过 2 和 3 的计算:它们是素数。请注意相等和条件或运算符的用法。 == 的优先级高于 ||操作员。所以我们不需要使用括号。
int i = (int) Math.Sqrt(num);
如果我们只尝试小于所讨论数字的平方根的数字,我们就可以了。数学证明,考虑到所讨论数字的平方根的值就足够了。
while (i > 1) {...i--; }
这是一个while循环。 i 是计算得出的数字的平方根。我们使用递减运算符在每个循环周期将 i 减一。当 i 小于 1 时,我们终止循环。例如,我们有数字 9。9 的平方根是 3。我们将 9 数字除以 3 和 2。
if (num % i == 0) {isPrime = false; }
这是算法的核心。如果余数除法运算符为任何 i 值返回 0,则所讨论的数字不是素数。
C#教程5:操作算子(2)相关推荐
- pyqt5 发送键盘信号_Python教程 | Pyqt5实战教程之操作交互处理,原来这么简单!...
PyQt5用来编写Python脚本的应用界面.本文详细介绍PyQt5教程之操作交互处理,并通过丰富的实战提高文章的可读性.在教程后面会附带PyQt5操作交互处理常见问题. 一.前言: 不管在PyQt还 ...
- js系列教程7-DOM操作全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: js系列教程1-数组操作全解 js系列教程2-对象和属性全解 js系列教程3-字符串和正则全解 js系列教程4-函数与参数全解 js系列教程5-容器和算 ...
- js系列教程6-BOM操作全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: js系列教程1-数组操作全解 js系列教程2-对象和属性全解 js系列教程3-字符串和正则全解 js系列教程4-函数与参数全解 js系列教程5-容器和算 ...
- jquery系列教程3-DOM操作全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件 ...
- Apifox 生成接口文档 教程与操作步骤
接口文档自动生成 本文主要介绍使用 apifox 如何生成接口文档,附上详细的使用教程和操作步骤. 使用Apifox 的可以自动生成接口文档.本文会给大家介绍下如何使用Apifox 来自动生成所需的接 ...
- python教程自带数据库_Python入门进阶教程-数据库操作
Python数据库操作Python版本3.8.0,开发工具:Pycharm 建议本节在掌握了数据库相关操作后再进行学习 MySQL 是最流行的关系型数据库管理系统.本小节通过Python对MySQL数 ...
- synopsys破解教程具体操作
synopsys破解教程具体操作 本破解已经验证适用2012.03以上各个版本,包括2015.06 下载对应版本的安装包 安装Installer_v3.2 并进入对应的文件夹,运行./setup.sh ...
- Selenium教程(4)操作选择框
目录 Selenium教程(1)选择和查找基本元素 Selenium教程(2)CSS元素操作 Selenium教程(3)IFrame切换/窗口切换 Selenium教程(4)操作选择框 1.选择框操作 ...
- 计算机应用基础与操作,计算机应用基础教程与操作实例(Windows7+Office2010)/21世纪高等职业教育规划教材·计算机公共课系列...
<计算机应用基础教程与操作实例(Windows7+Office2010)/21世纪高等职业教育规划教材·计算机公共课系列>结合高等职业教育培养高技能型人才的特点,根据教育部新制定的< ...
- 安装 MySql5.7 详细教程,操作简单(Windows版本)
文章目录 安装 MySql5.7 (解压版) 详细教程,操作简单(Windows版本) 1.官网下载MySql 2.解压,安装 3.环境变量 4.初始化数据库 5.安装MySql 6.启动或者停止服务 ...
最新文章
- K-近邻(KNN)算法
- cpu性能测试软件 国际象棋,国际象棋、科学计算,整机性能测试
- 鼠标右键转圈圈_鼠标右键文件夹出现转圈圈假死机情况
- iOS中的多线程一般使用场景
- Xamarin.Android 开发中遇到旋转屏幕错误
- Codeforces Round #703 (Div. 2) D . Max Median 二分 +思维
- 信息学奥赛一本通 1139:整理药名 | OpenJudge NOI 1.7 15
- 亚马逊股价继续大涨 首度突破每股800美元
- 知识分享|日本面试常考问题+巧妙回答①
- cocos2dx +vs2012安装教程
- 微信小程序列表局部(单条)刷新
- python贴吧顶贴_python实现贴吧顶贴机器人
- 嫡权法赋权法_1-熵值法赋权
- oracle存储过程语法累加,Oracle 存储过程语法总结及练习
- net start mongodb 发生系统错误 1058。
- img 格式相互转换 url, base64,blob, file
- proto—go语言生成代码参考(Generated-code reference中文翻译)
- java 撤销恢复按钮_java文本的撤销和恢复
- 【个人亲测】2018最流行的浏览器排行榜前10
- 推荐系统经典论文文献及业界应用