十、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)相关推荐

  1. pyqt5 发送键盘信号_Python教程 | Pyqt5实战教程之操作交互处理,原来这么简单!...

    PyQt5用来编写Python脚本的应用界面.本文详细介绍PyQt5教程之操作交互处理,并通过丰富的实战提高文章的可读性.在教程后面会附带PyQt5操作交互处理常见问题. 一.前言: 不管在PyQt还 ...

  2. js系列教程7-DOM操作全解

    全栈工程师开发手册 (作者:栾鹏) 快捷链接: js系列教程1-数组操作全解 js系列教程2-对象和属性全解 js系列教程3-字符串和正则全解 js系列教程4-函数与参数全解 js系列教程5-容器和算 ...

  3. js系列教程6-BOM操作全解

    全栈工程师开发手册 (作者:栾鹏) 快捷链接: js系列教程1-数组操作全解 js系列教程2-对象和属性全解 js系列教程3-字符串和正则全解 js系列教程4-函数与参数全解 js系列教程5-容器和算 ...

  4. jquery系列教程3-DOM操作全解

    全栈工程师开发手册 (作者:栾鹏) 快捷链接: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件 ...

  5. Apifox 生成接口文档 教程与操作步骤

    接口文档自动生成 本文主要介绍使用 apifox 如何生成接口文档,附上详细的使用教程和操作步骤. 使用Apifox 的可以自动生成接口文档.本文会给大家介绍下如何使用Apifox 来自动生成所需的接 ...

  6. python教程自带数据库_Python入门进阶教程-数据库操作

    Python数据库操作Python版本3.8.0,开发工具:Pycharm 建议本节在掌握了数据库相关操作后再进行学习 MySQL 是最流行的关系型数据库管理系统.本小节通过Python对MySQL数 ...

  7. synopsys破解教程具体操作

    synopsys破解教程具体操作 本破解已经验证适用2012.03以上各个版本,包括2015.06 下载对应版本的安装包 安装Installer_v3.2 并进入对应的文件夹,运行./setup.sh ...

  8. Selenium教程(4)操作选择框

    目录 Selenium教程(1)选择和查找基本元素 Selenium教程(2)CSS元素操作 Selenium教程(3)IFrame切换/窗口切换 Selenium教程(4)操作选择框 1.选择框操作 ...

  9. 计算机应用基础与操作,计算机应用基础教程与操作实例(Windows7+Office2010)/21世纪高等职业教育规划教材·计算机公共课系列...

    <计算机应用基础教程与操作实例(Windows7+Office2010)/21世纪高等职业教育规划教材·计算机公共课系列>结合高等职业教育培养高技能型人才的特点,根据教育部新制定的< ...

  10. 安装 MySql5.7 详细教程,操作简单(Windows版本)

    文章目录 安装 MySql5.7 (解压版) 详细教程,操作简单(Windows版本) 1.官网下载MySql 2.解压,安装 3.环境变量 4.初始化数据库 5.安装MySql 6.启动或者停止服务 ...

最新文章

  1. K-近邻(KNN)算法
  2. cpu性能测试软件 国际象棋,国际象棋、科学计算,整机性能测试
  3. 鼠标右键转圈圈_鼠标右键文件夹出现转圈圈假死机情况
  4. iOS中的多线程一般使用场景
  5. Xamarin.Android 开发中遇到旋转屏幕错误
  6. Codeforces Round #703 (Div. 2) D . Max Median 二分 +思维
  7. 信息学奥赛一本通 1139:整理药名 | OpenJudge NOI 1.7 15
  8. 亚马逊股价继续大涨 首度突破每股800美元
  9. 知识分享|日本面试常考问题+巧妙回答①
  10. cocos2dx +vs2012安装教程
  11. 微信小程序列表局部(单条)刷新
  12. python贴吧顶贴_python实现贴吧顶贴机器人
  13. 嫡权法赋权法_1-熵值法赋权
  14. oracle存储过程语法累加,Oracle 存储过程语法总结及练习
  15. net start mongodb 发生系统错误 1058。
  16. img 格式相互转换 url, base64,blob, file
  17. proto—go语言生成代码参考(Generated-code reference中文翻译)
  18. java 撤销恢复按钮_java文本的撤销和恢复
  19. 【个人亲测】2018最流行的浏览器排行榜前10
  20. 推荐系统经典论文文献及业界应用

热门文章

  1. python应用实战案例:python如何实现异步爬虫?
  2. python中nltk_python2.7和NLTK安装详细教程
  3. excel只对筛选后的结果单独用公式
  4. 【LeetCode从零单排】No36 Valid Sudoku
  5. 25个Java机器学习工具库--转载
  6. Java多线程编程模式实战指南(三):Two-phase Termination模式--转载
  7. 使用native 查询时,对特殊字符的处理。
  8. 机器学习Sklearn实战——其他线性模型
  9. 【项目管理】敏捷开发项目管理流程
  10. 【风控建模】互联网金融-机器学习及评分卡构建