C# 运算符

来源:这里教程网 时间:2026-02-17 08:44:19 作者:

C# 运算符,表达式是根据操作数和运算符构造的。 表达式的运算符指示将哪些运算应用于操作数。 表达式中运算符的求值顺序由运算符的优先级和关联性确定

运算符是特殊符号,表示已执行某个过程。 编程语言的运算符来自数学。 程序员处理数据。 运算符用于处理数据。 操作数是运算符的输入(参数)之一。

C# 运算符列表

下表显示了 C# 语言中使用的一组运算符。

类别符号
符号运算符+ -
算术+ - * / %
逻辑(布尔和按位)& | ^ ! ~ && || true false
字符串连接+
递增,递减++ --
移位<< >>
关系== != < > <= >=
辅助= += -= *= /= %= &= &#124;= ^= ??= <<= >>=
成员访问. ?.
索引[] ?[]
调用()
三元?:
委托连接和删除+ -
对象创建new
类型信息as is sizeof typeof
异常控制checked unchecked
间接地址* -> [] &
Lambda=>

一个运算符通常有一个或两个操作数。 那些仅使用一个操作数的运算符称为一元运算符。 那些使用两个操作数的对象称为二进制运算符。 还有一个三元运算符?:,它可以处理三个操作数。

某些运算符可以在不同的上下文中使用。 例如+运算符。 从上表中我们可以看到它在不同情况下使用。 它添加数字,连接字符串或委托; 表示数字的符号。 我们说运算符是重载。

C# 一元运算符

C# 一元运算符包括:+,-,++,-,强制转换运算符()和否定!。

C# 符号运算符

有两个符号运算符:+和-。 它们用于指示或更改值的符号。

Program.cs

using System;namespace MinusSign{    class Program    {        static void Main(string[] args)        {            Console.WriteLine(2);            Console.WriteLine(+2);            Console.WriteLine(-2);        }    }}

+和-符号指示值的符号。 加号可以用来表示我们有一个正数。 可以将其省略,并且通常可以这样做。

Program.cs

using System;public class MinusSign{    static void Main()    {        int a = 1;        Console.WriteLine(-a);        Console.WriteLine(-(-a));    }}

减号更改值的符号。

$ dotnet run-11

这是输出。

C# 增减运算符

将值递增或递减一个是编程中的常见任务。 C# 为此有两个方便的运算符:++和--。

x++;x = x + 1;...y--;y = y - 1;

上面两对表达式的作用相同。

Program.cs

using System;namespace IncrementDecrement{    class Program    {        static void Main(string[] args)        {            int x = 6;            x++;            x++;            Console.WriteLine(x);            x--;            Console.WriteLine(x);        }    }}

在上面的示例中,我们演示了两个运算符的用法。

int x = 6;x++;x++;

将x变量初始化为 6。然后将x递增两次。 现在变量等于 8。

x--;

我们使用减量运算符。 现在变量等于 7。

$ dotnet run87

C# 显式强制转换运算符

显式强制转换运算符()可用于将一个类型强制转换为另一个类型。 请注意,此运算符仅适用于某些类型。

Program.cs

using System;namespace CastOperator{    class Program    {        static void Main(string[] args)        {            float val = 3.2f;            int num = (int) val;            System.Console.WriteLine(num);        }    }}

在该示例中,我们将float类型显式转换为int。

求反运算符

取反运算符(!)反转其操作数的含义。

Program.cs

using System;namespace Negation{    class Program    {        static void Main(string[] args)        {            var isValid = false;            if (!isValid)            {                Console.WriteLine("The option is not valid");            }        }    }}

在该示例中,我们建立了一个否定条件:如果表达式的逆数有效,则执行该条件。

C# 赋值运算符

赋值运算符=将值赋给变量。 变量是值的占位符。 在数学中,=运算符具有不同的含义。 在等式中,=运算符是一个相等运算符。 等式的左侧等于右侧。

int x = 1;

在这里,我们为x变量分配一个数字。

x = x + 1;

先前的表达式在数学上没有意义。 但这在编程中是合法的。 该表达式将x变量加 1。 右边等于 2,并且 2 分配给x。

3 = x;

此代码示例导致语法错误。 我们无法为文字分配值。

C# 连接字符串

+运算符还用于连接字符串。

Program.cs

using System;namespace Concatenate{    class Program    {        static void Main(string[] args)        {            Console.WriteLine("Return " + "of " + "the king.");        }    }}

我们使用字符串连接运算符将三个字符串连接在一起。

$ dotnet runReturn of the king.

这是该计划的结果。

C# 算术运算符

下表是 C# 中的算术运算符表。

Symbol名称
+加法
-减法
*乘法
/除法
%余数

以下示例显示了算术运算。

Project.cs

using System;namespace Arithmetic{    class Program    {        static void Main(string[] args)        {            int a = 10;            int b = 11;            int c = 12;            int add = a + b + c;            int sb = c - a;            int mult = a * b;            int div = c / 3;            int rem = c % a;            Console.WriteLine(add);            Console.WriteLine(sb);            Console.WriteLine(mult);            Console.WriteLine(div);            Console.WriteLine(rem);        }    }}

在前面的示例中,我们使用加法,减法,乘法,除法和余数运算。 这些都是数学所熟悉的。

int rem = c % a;

%运算符称为余数或模运算符。 它找到一个数除以另一个的余数。 例如9 % 4,9 模 4 为 1,因为 4 两次进入 9 且余数为 1。

$ dotnet run33211042

这是示例的输出。

接下来,我们将说明整数除法和浮点除法之间的区别。

Program.cs

using System;namespace Division{    class Program    {        static void Main(string[] args)        {            int c = 5 / 2;            Console.WriteLine(c);            double d = 5 / 2.0;            Console.WriteLine(d);        }    }}

在前面的示例中,我们将两个数字相除。

int c = 5 / 2;Console.WriteLine(c);

在这段代码中,我们完成了整数除法。 除法运算的返回值为整数。 当我们将两个整数相除时,结果是一个整数。

double d = 5 / 2.0;Console.WriteLine(d);

如果值之一是 double 或 float,则执行浮点除法。 在我们的例子中,第二个操作数是双精度数,因此结果是双精度数。

$ dotnet run22.5

我们看到了程序的结果。

C# 布尔运算符

在 C# 中,我们有三个逻辑运算符。 bool关键字用于声明布尔值。

符号名称
&&逻辑与
||逻辑或
!否定

布尔运算符也称为逻辑运算符。

Program.cs

using System;namespace Boolean{    class Program    {        static void Main(string[] args)        {            int x = 3;            int y = 8;            Console.WriteLine(x == y);            Console.WriteLine(y > x);            if (y > x)            {                Console.WriteLine("y is greater than x");            }        }    }}

许多表达式导致布尔值。 布尔值用于条件语句中。

Console.WriteLine(x == y);Console.WriteLine(y > x);

关系运算符始终导致布尔值。 这两行分别显示 false 和 true。

if (y > x){    Console.WriteLine("y is greater than x");}

仅在满足括号内的条件时才执行if语句的主体。 y > x返回 true,因此消息“ y 大于 x”被打印到终端。

true和false关键字表示 C# 中的布尔文字。

Program.cs

using System;namespace AndOperator{    class Program    {        static void Main(string[] args)        {            bool a = true && true;            bool b = true && false;            bool c = false && true;            bool d = false && false;            Console.WriteLine(a);            Console.WriteLine(b);            Console.WriteLine(c);            Console.WriteLine(d);        }    }}

示例显示了逻辑和运算符。 仅当两个操作数均为 true 时,它的评估结果为 true。

$ dotnet runTrueFalseFalseFalse

True只产生一个表达式。

如果两个操作数中的任何一个为 true,则逻辑或||运算符的计算结果为 true。

Program.cs

using System;namespace OrOperator{    class Program    {        static void Main(string[] args)        {            bool a = true || true;            bool b = true || false;            bool c = false || true;            bool d = false || false;            Console.WriteLine(a);            Console.WriteLine(b);            Console.WriteLine(c);            Console.WriteLine(d);        }    }}

如果运算符的任一侧为真,则操作的结果为真。

$ dotnet runTrueTrueTrueFalse

四个表达式中的三个表示为 true。

否定运算符!将 true 设为 false,并将 false 设为 false。

Program.cs

using System;namespace NegationEx{    class Program    {        static void Main(string[] args)        {            Console.WriteLine(!true);            Console.WriteLine(!false);            Console.WriteLine(!(4 < 3));        }    }}

该示例显示了否定运算符的作用。

$ dotnet runFalseTrueTrue

这是negation.exe程序的输出。

||和&&运算符经过短路评估。 短路评估意味着仅当第一个参数不足以确定表达式的值时,才评估第二个参数:当逻辑的第一个参数的结果为 false 时,总值必须为 false ; 当逻辑或的第一个参数为 true 时,总值必须为 true。 短路评估主要用于提高性能。

一个例子可以使这一点更加清楚。

Program.cs

using System;namespace ShortCircuit{    class Program    {        static void Main(string[] args)        {            Console.WriteLine("Short circuit");            if (One() && Two())            {                Console.WriteLine("Pass");            }            Console.WriteLine("#############");            if (Two() || One())            {                Console.WriteLine("Pass");            }        }        public static bool One()        {            Console.WriteLine("Inside one");            return false;        }        public static bool Two()        {            Console.WriteLine("Inside two");            return true;        }    }}

在示例中,我们有两种方法。 它们在布尔表达式中用作操作数。 我们将看看它们是否被调用。

if (One() && Two()){    Console.WriteLine("Pass");}

One()方法返回false。 短路& &不评估第二种方法。 没有必要。 一旦操作数为false,则逻辑结论的结果始终为false。 仅将“ Inside one”打印到控制台。

Console.WriteLine("#############");if (Two() || One()){    Console.WriteLine("Pass");}

在第二种情况下,我们使用||运算符,并使用Two()方法作为第一个操作数。 在这种情况下,“ Inside two”和“ Pass”字符串将打印到终端。 再次不必评估第二操作数,因为一旦第一操作数评估为true,则逻辑或始终为true。

$ ShortCircuit>dotnet runShort circuitInside one#############Inside twoPass

C# 关系运算符

关系运算符用于比较值。 这些运算符总是产生布尔值。

符号含义
<小于
<=小于或等于
>大于
>=大于或等于
==等于
!=不等于

关系运算符也称为比较运算符。

Program.cs

using System;namespace Relational{    class Program    {        static void Main(string[] args)        {            Console.WriteLine(3 < 4);            Console.WriteLine(3 == 4);            Console.WriteLine(4 >= 3);            Console.WriteLine(4 != 3);        }    }}

在代码示例中,我们有四个表达式。 这些表达式比较整数值。 每个表达式的结果为 true 或 false。 在 C# 中,我们使用==比较数字。 某些语言(例如 Ada,Visual Basic 或 Pascal)使用=比较数字。

C# 按位运算符

小数对人类是自然的。 二进制数是计算机固有的。 二进制,八进制,十进制或十六进制符号仅是相同数字的符号。 按位运算符使用二进制数的位。 像 C# 这样的高级语言很少使用按位运算符。

符号含义
~按位取反
^按位异或
&按位与
|按位或

按位取反运算符分别将 1 更改为 0,将 0 更改为 1。

Console.WriteLine(~ 7); // prints -8Console.WriteLine(~ -8); // prints 7

运算符恢复数字 7 的所有位。这些位之一还确定数字是否为负。 如果我们再一次对所有位取反,我们将再次得到 7。

按位,运算符在两个数字之间进行逐位比较。 仅当操作数中的两个对应位均为 1 时,位位置的结果才为 1。

      00110   &  00011   =  00010

第一个数字是二进制表示法 6,第二个数字是 3,结果是 2。

Console.WriteLine(6 & 3); // prints 2Console.WriteLine(3 & 6); // prints 2

按位或运算符在两个数字之间进行逐位比较。 如果操作数中的任何对应位为 1,则位位置的结果为 1。

     00110   | 00011   = 00111

结果为00110或十进制 7。

Console.WriteLine(6 | 3); // prints 7Console.WriteLine(3 | 6); // prints 7

按位互斥或运算符在两个数字之间进行逐位比较。 如果操作数中对应位中的一个或另一个(但不是全部)为 1,则位位置的结果为 1。

      00110   ^  00011   =  00101

结果为00101或十进制 5。

Console.WriteLine(6 ^ 3); // prints 5Console.WriteLine(3 ^ 6); // prints 5

C# 复合赋值运算符

复合赋值运算符由两个运算符组成。 他们是速记员。

a = a + 3;a += 3;

+=复合运算符是这些速记运算符之一。 以上两个表达式相等。 将值 3 添加到变量 a 中。

其他复合运算符是:

-=   *=   /=   %=   &=   |=   <<=   >>=

Program.cs

using System;namespace CompoundOperators{    class Program    {        static void Main(string[] args)        {            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 run2721

这是示例输出。

C# new运算符

new运算符用于创建对象和调用构造函数。

Program.cs

using System;namespace NewOperator{    class Being    {        public Being()        {            Console.WriteLine("Being created");        }    }    class Program    {        static void Main(string[] args)        {            var b = new Being();            Console.WriteLine(b);            var vals = new int[] { 1, 2, 3, 4, 5 };            System.Console.WriteLine(string.Join(" ", vals));        }    }}

在示例中,我们使用new运算符创建了一个新的自定义对象和一个整数数组。

public Being(){    Console.WriteLine("Being created");}

这是一个构造函数。 在创建对象时调用它。

$ dotnet runBeing createdNewOperator.Being1 2 3 4 5

C# 访问运算符

访问运算符[]与数组,索引器和属性一起使用。

Program.cs

using System;using System.Collections.Generic;namespace AccessOperator{    class Program    {        static void Main(string[] args)        {            var vals = new int[] { 2, 4, 6, 8, 10 };            Console.WriteLine(vals[0]);            var domains = new Dictionary<string, string>()            {                { "de", "Germany" },                { "sk", "Slovakia" },                { "ru", "Russia" }            };            Console.WriteLine(domains["de"]);            oldMethod();        }        [Obsolete("Don't use OldMethod, use NewMethod instead", false)]        public static void oldMethod()        {            Console.WriteLine("oldMethod()");        }        public static 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()");}

我们激活了内置的Obsolete属性。 该属性发出警告。

$ dotnet runProgram.cs(22,13): warning CS0618: 'Program.oldMethod()' is obsolete:'Don't use OldMethod, use NewMethod instead'[C:\Users\Jano\Documents\csharp\tutorial\AccessOperator\AccessOperator.csproj]2GermanyoldMethod()

C# 索引的最终运算符^

结束运算符^的索引指示从序列结尾开始的元素位置。 例如,^1指向序列的最后一个元素,^n指向偏移为length - n的元素。

Program.cs

using System;using System.Linq;namespace IndexFromEnd{    class Program    {        static void Main(string[] args)        {            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 run54n

C# 范围运算符..

..运算符指定索引范围的开始和结束作为其操作数。 左侧操作数是范围的一个包含范围的开始。 右侧操作数是范围的排他端。

x.. is equivalent to x..^0..y is equivalent to 0..y.. is equivalent to 0..^0

可以省略..运算符的操作数以获取开放范围。

Program.cs

using System;namespace RangeOperator{    class Program    {        static void Main(string[] args)        {            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

using System;namespace SizeType{    class Program    {        static void Main(string[] args)        {            Console.WriteLine(sizeof(int));            Console.WriteLine(sizeof(float));            Console.WriteLine(sizeof(Int32));            Console.WriteLine(typeof(int));            Console.WriteLine(typeof(float));        }    }}

我们使用sizeof和typeof运算符。

$ dotnet run444System.Int32

我们可以看到int类型是System.Int32的别名,float是System.Single类型的别名。

is操作符检查对象是否与给定类型兼容。

Program.cs

using System;namespace IsOperator{    class Base { }    class Derived : Base { }    class Program    {        static void Main(string[] args)        {            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 {}

我们有一个Base和Derived类。 Derived类继承自Base类。

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类兼容,因为它显式继承自Base类。 另一方面,_base对象与Derived类无关。

$ dotnet runTrueTrueTrueFalse

这是示例的输出。

as运算符用于在兼容的参考类型之间执行转换。 如果无法进行转换,则运算符将返回 null。 与强制转换操作不同,后者引发异常。

Program.cs

using System;namespace AsOperator{    class Base { }    class Derived : Base { }    class Program    {        static void Main(string[] args)        {            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");                }            }        }    }}

在上面的示例中,我们使用as运算符执行转换。

string s = objects[i] as string;

我们尝试将各种类型转换为字符串类型。 但只有一次转换有效。

$ dotnet run0:not a string1:not a string2:ZetCode3:not a string4:not a string5:not a string

C# 运算符优先级

运算符优先级告诉我们首先评估哪个运算符。 优先级对于避免表达式中的歧义是必要的。

以下表达式 28 或 40 的结果是什么?

3 + 5 * 5

像数学中一样,乘法运算符的优先级高于加法运算符。 结果是 28。

(3 + 5) * 5

要更改评估的顺序,可以使用括号。 括号内的表达式始终首先被求值。

下表显示了按优先级排序的通用 C# 运算符(优先级最高):

运算符类别关联性
x.y x?.y, x?[y] f(x) a[x] x++ x-- new typeof default checked unchecked
一元+ - ! ~ ++x --x (T)x
乘法* / %
加法+ -
移位<< >>
相等== !=
逻辑与&
逻辑异或^
逻辑或|
条件与&&
条件或||
空合并??
三元?:
赋值= *= /= %= += -= <<= >>= &= ^= &#124;= ??= =>

表的同一行上的运算符具有相同的优先级。

Program.cs

using System;namespace Precedence{    class Program    {        static void Main(string[] args)        {            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);

在这种情况下,否定运算符具有更高的优先级。 首先,将第一个 true 值取反为 false,然后|运算符将 false 和 true 组合在一起,最后给出 true。

$ dotnet run2840TrueFalse

这是precedence.exe程序的结果。

C# 关联规则

有时,优先级不能令人满意地确定表达式的结果。 还有另一个规则称为关联性。 运算符的关联性确定优先级与相同的运算符的评估顺序。

9 / 3 * 3

此表达式的结果是 9 还是 1? 乘法,删除和模运算符从左到右关联。 因此,该表达式的计算方式为:(9 / 3) * 3,结果为 9。

算术,布尔,关系和按位运算符都是从左到右关联的。

另一方面,赋值运算符是正确关联的。

Program.cs

using System;namespace Associativity{    class Program    {        static void Main(string[] args)        {            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 run0 0 0 00

C# 空条件运算符

空条件运算符仅在该操作数的值为非空时才将成员访问?.或元素访问 ?[]应用于其操作数。 如果操作数的值为null,则应用运算符的结果为 null。

Program.cs

using System;using System.Collections.Generic;namespace NullConditional{    class User    {        public User() { }        public User(string name, string occupation)        {            this.name = name;            this.occupation = occupation;        }        public string name { get; set; }        public string occupation { get; set; }        public override string ToString() => $"{name} {occupation}";    }    class Program    {        static void Main(string[] args)        {            var users = new List<User>() { new User("John Doe", "gardener"), new User(),                    new User("Lucia Newton", "teacher") };            users.ForEach(user => Console.WriteLine(user.name?.ToUpper()));        }    }}

在示例中,我们有一个带有两个成员的User类:name和occupation。 我们在?.运算符的帮助下访问对象的name成员。

var users = new List<User>() { new User("John Doe", "gardener"), new User(),    new User("Lucia Newton", "teacher") };

我们有一个用户列表。 其中一个未初始化,因此其成员为null。

users.ForEach(user => Console.WriteLine(user.name?.ToUpper()));

我们使用?.访问name成员并调用ToUpper()方法。 ?.通过不调用null值上的ToUpper()来防止System.NullReferenceException。

$ dotnet runJOHN DOELUCIA NEWTON

在下面的示例中,我们使用[].运算符。

Program.cs

using System;namespace NullConditional2{    class Program    {        static void Main(string[] args)        {            int?[] vals = { 1, 2, 3, null, 4, 5 };            int i = 0;            while (i < vals.Length)            {                Console.WriteLine(vals[i]?.GetType());                i++;            }        }    }}

在此示例中,我们在数组中有一个null值。 我们通过在数组元素上应用[].运算符来防止System.NullReferenceException。

C# 空值运算符

空合并运算符??用于定义nullable类型的默认值。 如果不为 null,则返回左侧操作数;否则返回 0。 否则返回正确的操作数。 当我们使用数据库时,我们经常处理缺失的值。 这些值在程序中为空。 该运算符是处理此类情况的便捷方法。

Program.cs

using System;namespace NullCoalescing{    class Program    {        static void Main(string[] args)        {            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>的简写。 它允许将空值分配给int类型。

int z = x ?? y ?? -1;

我们要为z变量分配一个值。 但是它一定不是null。 这是我们的要求。 我们可以轻松地为此使用 null-coalescing 运算符。 如果x和y变量均为空,我们将-1 分配给z。

$ dotnet run-1

这是程序的输出。

C# 空折叠赋值运算符

仅当左侧操作数的值为null时,空合并赋值运算符??=才将其右侧操作数的值分配给其左侧操作数。 如果??=运算符的左手操作数取值为非空,则不计算其右手操作数。 它在 C# 8.0 和更高版本中可用。

Program.cs

using System;using System.Collections.Generic;namespace NullCoalescingAssignment{    class Program    {        static void Main(string[] args)        {            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));        }    }}

在该示例中,我们在整数值列表上使用 null-coalescing 赋值运算符。

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};

我们尝试为变量分配一个新的列表对象。 由于该变量不再是null,因此不会分配该列表。

$ dotnet run1, 2, 3, 4, 5, 6, 7, 8, 91, 2, 3, 4, 5, 6, 7, 8, 9

This is the output.

C# 三元运算符

三元运算符?:是条件运算符。 对于要根据条件表达式选择两个值之一的情况,它是一个方便的运算符。

cond-exp ? exp1 : exp2

如果 cond-exp 为 true,则评估 exp1 并返回结果。 如果 cond-exp 为 false,则评估 exp2 并返回其结果。

Program.cs

using System;namespace Ternary{    class Program    {        static void Main(string[] args)        {            int age = 31;            bool adult = age >= 18 ? true : false;            Console.WriteLine("Adult: {0}", adult);        }    }}

在大多数国家/地区,成年取决于您的年龄。 如果您的年龄超过特定年龄,则您已经成年。 对于三元运算符,这是一种情况。

bool adult = age >= 18 ? true : false;

首先,对赋值运算符右侧的表达式进行求值。 三元运算符的第一阶段是条件表达式评估。 因此,如果年龄大于或等于 18,则返回?字符后的值。 如果不是,则返回:字符后的值。 然后将返回值分配给成人变量。

$ dotnet runAdult: True

31 岁的成年人是成年人。

C# Lambda 运算符

=>令牌称为 lambda 运算符。 它是从功能语言中提取的运算符。 该运算符可以使代码更短,更清晰。 另一方面,理解语法可能很棘手。 特别是如果程序员以前从未使用过函数式语言。

只要可以使用委托,我们都可以使用 lambda 表达式。 lambda 表达式的定义是:lambda 表达式是一个匿名函数,可以包含表达式和语句。 左边是一组数据,右边是表达式或语句块。 这些语句应用于数据的每个项目。

在 lambda 表达式中,我们没有 return 关键字。 最后一条语句自动返回。 而且,我们不需要为参数指定类型。 编译器将猜测正确的参数类型。 这称为类型推断。

Program.cs

using System;using System.Collections.Generic;namespace LambdaOperator{    class Program    {        static void Main(string[] args)        {            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 run864795

大于 3 的整数列表中的值。

Program.cs

using System;using System.Collections.Generic;namespace AnonymousDelegate{    class Program    {        static void Main(string[] args)        {            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

using System;namespace Primes{    class Program    {        static void Main(string[] args)        {            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;

根据定义,1 不是质数

if (num == 2 || num == 3){    Console.Write(num + " ");    continue;}

我们跳过 2 和 3 的计算,它们是质数。 请注意等式和条件或运算符的用法。 ==的优先级高于||运算符。 因此,我们不需要使用括号。

int i = (int) Math.Sqrt(num);

如果我们仅尝试小于所讨论数字的平方根的数字,那么我们可以。

while (i > 1){    ...    i--;}

这是一个 while 循环。 i是计算出的数字的平方根。 我们使用减量运算符将每个循环周期的 i 减 1。 当 i 小于 1 时,我们终止循环。 例如,我们有 9。9 的平方根是 3。我们将 9 的数字除以 3 和 2。这对于我们的计算就足够了。

if (num % i == 0){    isPrime = false;}

这是算法的核心。 如果余数除法运算符对于任何 i 值返回 0,则说明所讨论的数字不是质数。

相关推荐