C#教程5:操作算子(2)
十、C#?復(fù)合賦值運算符
復(fù)合賦值運算符由兩個運算符組成。他們是速記運算符。
a = a + 3; a += 3;+= 復(fù)合運算符是這些速記運算符之一。上面兩個表達式是相等的。值 3 被添加到 a 變量中。
其他復(fù)合運算符有:
-= *= /= %= &= |= <<= >>=Program.cs
int a = 1; a = a + 1;Console.WriteLine(a);a += 5; Console.WriteLine(a);a *= 3; Console.WriteLine(a);在示例中,我們使用了兩個復(fù)合運算符。
int a = 1; a = a + 1;a 變量初始化為 1。使用非速記符號將 1 添加到變量中。
a += 5;使用 += 復(fù)合運算符,我們將 5 添加到 a 變量。該語句等于 a = a + 5;。
a *= 3;使用 *= 運算符,a 乘以 3。語句等于 a = a * 3;。
$ dotnet run 2 7 21十一、C# new操作符
new 運算符用于創(chuàng)建對象和調(diào)用構(gòu)造函數(shù)。
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 運算符創(chuàng)建了一個新的自定義對象和一個整數(shù)數(shù)組。
public Being() {Console.WriteLine("Being created"); }這是一個構(gòu)造函數(shù)。它在對象創(chuàng)建時被調(diào)用。
$ dotnet run Being created Being 1 2 3 4 5十二、C# 訪問運算符
訪問運算符 [] 與數(shù)組、索引器和屬性一起使用。
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()"); }在示例中,我們使用 [] 運算符獲取數(shù)組元素、字典對的值并激活內(nèi)置屬性。
var vals = new int[] { 2, 4, 6, 8, 10 }; Console.WriteLine(vals[0]);我們定義了一個整數(shù)數(shù)組。我們使用 vals[0] 獲得第一個元素。
var domains = new Dictionary<string, string>() {{ "de", "Germany" },{ "sk", "Slovakia" },{ "ru", "Russia" } };Console.WriteLine(domains["de"]);創(chuàng)建了一個字典。使用 domains["de"],我們得到具有 "de" 鍵的對的值。
[Obsolete("Don't use OldMethod, use NewMethod instead", false)] public static void oldMethod() {Console.WriteLine("oldMethod()"); }我們激活了內(nèi)置的過時屬性。該屬性發(fā)出警告。
當(dāng)我們運行程序時,它會產(chǎn)生警告:warning CS0618: 'oldMethod()' is obsolete: 'Don't use OldMethod, use NewMethod instead'。
十三、C# 索引符號 ^
結(jié)束運算符 ^ 的索引表示從序列末尾開始的元素位置。例如,^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]);在示例中,我們將運算符應(yīng)用于數(shù)組和字符串。
int[] vals = { 1, 2, 3, 4, 5 };Console.WriteLine(vals[^1]); Console.WriteLine(vals[^2]);我們打印數(shù)組的最后一個元素和最后一個元素。
var word = "gray falcon";Console.WriteLine(word[^1]);我們打印單詞的最后一個字母。
$ dotnet run 5 4 n十四、C# 范圍操作符..
.. 運算符將索引范圍的開始和結(jié)束指定為其操作數(shù)。左邊的操作數(shù)是一個范圍的包含開始。右手操作數(shù)是一個范圍的唯一結(jié)束。
x.. is equivalent to x..^0 ..y is equivalent to 0..y .. is equivalent to 0..^0.. 運算符的操作數(shù)可以省略以獲得開放范圍。
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));在示例中,我們使用 .. 運算符來獲取數(shù)組切片。
var range1 = vals[1..4]; Console.WriteLine("[{0}]", string.Join(", ", range1));我們創(chuàng)建一個從索引 1 到索引 4 的數(shù)組切片;最后一個索引 4 不包括在內(nèi)。
var slice2 = vals[..^0]; Console.WriteLine("[{0}]", string.Join(", ", slice2));在這里,我們基本上創(chuàng)建了數(shù)組的副本。
$ dotnet run [2, 3, 4] [1, 2, 3, 4, 5, 6, 7]十五、C# 類型信息
現(xiàn)在我們關(guān)注使用類型的運算符。
sizeof 運算符用于獲取值類型的大小(以字節(jié)為單位)。 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 { }我們從用戶定義的類型創(chuàng)建兩個對象。
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 類無關(guān)。
$ dotnet run True True True Falseas 運算符用于在兼容的引用類型之間執(zhí)行轉(zhuǎn)換。當(dāng)無法進行轉(zhuǎn)換時,運算符返回 null。與引發(fā)異常的強制轉(zhuǎn)換操作不同。
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 運算符來執(zhí)行轉(zhuǎn)換。
string s = objects[i] as string;我們嘗試將各種類型轉(zhuǎn)換為字符串類型。但只有一次鑄造有效。
$ 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#?運算符優(yōu)先級
運算符優(yōu)先級告訴我們首先評估哪些運算符。優(yōu)先級對于避免表達式中的歧義是必要的。
以下表達式的結(jié)果是 28 還是 40?
3 + 5 * 5與數(shù)學(xué)一樣,乘法運算符的優(yōu)先級高于加法運算符。所以結(jié)果是28。
(3 + 5) * 5要更改或提高優(yōu)先級,我們可以使用括號。括號內(nèi)的表達式總是首先被計算。
下表顯示了按優(yōu)先級排序的常見 C# 運算符(最高優(yōu)先級在前)
| 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 |
表同一行上的運算符具有相同的優(yōu)先級。
Program.cs
Console.WriteLine(3 + 5 * 5); Console.WriteLine((3 + 5) * 5);Console.WriteLine(! true | true); Console.WriteLine(! (true | true));在此代碼示例中,我們展示了一些表達式。每個表達式的結(jié)果取決于優(yōu)先級。
Console.WriteLine(3 + 5 * 5);此行打印 28。乘法運算符的優(yōu)先級高于加法。首先計算 5*5 的乘積,然后加上 3。
Console.WriteLine(! true | true);在這種情況下,否定運算符具有更高的優(yōu)先級。首先,第一個真值被否定為假,然后 |運算符將 false 和 true 組合在一起,最終給出 true。
$ dotnet run 28 40 True False十七、C#?關(guān)聯(lián)規(guī)則
有時,優(yōu)先級不能令人滿意地確定表達式的結(jié)果。還有另一條規(guī)則稱為關(guān)聯(lián)性。運算符的關(guān)聯(lián)性決定了具有相同優(yōu)先級的運算符的評估順序。
9 / 3 * 3這個表達式的結(jié)果是 9 還是 1?乘法、刪除和模運算符從左到右關(guān)聯(lián)。所以表達式是這樣計算的:(9 / 3) * 3,結(jié)果是 9。
算術(shù)、布爾、關(guān)系和位運算符都是從左到右關(guān)聯(lián)的。
另一方面,賦值運算符是右關(guān)聯(lián)的。
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);在示例中,我們有兩種情況,其中關(guān)聯(lián)性規(guī)則決定了表達式。
int a, b, c, d; a = b = c = d = 0;賦值運算符是從右到左關(guān)聯(lián)的。如果關(guān)聯(lián)性是從左到右的,則前面的表達式是不可能的。
int j = 0; j *= 3 + 1;復(fù)合賦值運算符是從右到左關(guān)聯(lián)的。我們可能期望結(jié)果為 1。但實際結(jié)果為 0。因為關(guān)聯(lián)性。首先計算右側(cè)的表達式,然后應(yīng)用復(fù)合賦值運算符。
$ dotnet run 0 0 0 0 0十八、 C#??空條件運算符
僅當(dāng)操作數(shù)的計算結(jié)果為非 null 時,null 條件運算符才會將成員訪問、?. 或元素訪問、?[] 操作應(yīng)用于其操作數(shù)。如果操作數(shù)的計算結(jié)果為 null,則應(yīng)用運算符的結(jié)果為 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);在示例中,我們有一個包含兩個成員的用戶類:姓名和職業(yè)。我們在 ? 的幫助下訪問對象的名稱成員。操作員。
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 成員并調(diào)用 ToUpper 方法。這 ?。通過不對 null 值調(diào)用 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++; }在此示例中,我們在數(shù)組中有一個空值。我們通過應(yīng)用 ? 來防止 System.NullReferenceException。數(shù)組元素上的運算符。
十九、C#?空合并運算符
????????空合并運算符??用于定義可空類型的默認(rèn)值。如果它不為空,則返回左操作數(shù);否則返回正確的操作數(shù)。當(dāng)我們使用數(shù)據(jù)庫時,我們經(jīng)常處理缺失值。這些值作為程序的空值出現(xiàn)。此運算符是處理此類情況的便捷方式。
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#?空合并賦值運算符
????????僅當(dāng)左側(cè)操作數(shù)的計算結(jié)果為 null 時,null 合并賦值運算符 ??= 才將其右側(cè)操作數(shù)的值分配給其左側(cè)操作數(shù)。如果左側(cè)操作數(shù)的計算結(jié)果為非空,則??= 運算符不計算其右側(cè)操作數(shù)。它在 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));在示例中,我們對整數(shù)值列表使用空合并賦值運算符。
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));我們向列表中添加一些值并打印其內(nèi)容。
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#?三元運算符
三元運算符?: 是一個條件運算符。對于我們想要根據(jù)條件表達式選擇兩個值之一的情況,它是一個方便的運算符。
cond-exp ? exp1 : exp2如果 cond-exp 為真,則計算 exp1 并返回結(jié)果。如果 cond-exp 為假,則計算 exp2 并返回其結(jié)果。
Program.cs
int age = 31;bool adult = age >= 18 ? true : false;Console.WriteLine("Adult: {0}", adult);在大多數(shù)國家,成年期取決于您的年齡。如果您超過某個年齡,您就是成年人。這是三元運算符的情況。
bool adult = age >= 18 ? true : false;首先評估賦值運算符右側(cè)的表達式。三元運算符的第一階段是條件表達式求值。因此,如果年齡大于或等于 18,則后面的值是?返回字符。如果不是,則返回 : 字符后面的值。然后將返回的值分配給成人變量。
$ dotnet run Adult: TrueA 31 years old person is adult.
二十二、C# Lambda操作符號
????????=> 標(biāo)記稱為 lambda 運算符。它是取自函數(shù)式語言的運算符。該運算符可以使代碼更短更清晰。另一方面,理解語法可能很棘手。特別是如果程序員以前從未使用過函數(shù)式語言。
????????只要我們可以使用委托,我們也可以使用 lambda 表達式。 lambda 表達式的定義是:lambda 表達式是一個匿名函數(shù),可以包含表達式和語句。左側(cè)是一組數(shù)據(jù),右側(cè)是表達式或語句塊。這些陳述適用于每一項數(shù)據(jù)。
????????在 lambda 表達式中,我們沒有 return 關(guān)鍵字。最后一條語句會自動返回。而且我們不需要為我們的參數(shù)指定類型。編譯器將猜測正確的參數(shù)類型。這稱為類型推斷。
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); }我們有一個整數(shù)列表。我們打印所有大于 3 的數(shù)字。
var list = new List<int>() { 3, 2, 1, 8, 6, 4, 7, 9, 5 };我們有一個通用的整數(shù)列表。
var subList = list.FindAll(val => val > 3);這里我們使用 lambda 運算符。 FindAll 方法將謂詞作為參數(shù)。謂詞是一種特殊的委托,它返回一個布爾值。謂詞適用于列表的所有項目。 val 是一個沒有類型指定的輸入?yún)?shù)。我們可以顯式指定類型,但這不是必需的。
編譯器需要一個 int 類型。 val 是列表中的當(dāng)前輸入值。比較它是否大于 3 并返回布爾值 true 或 false。最后,FindAll 將返回滿足條件的所有值。它們被分配給子列表集合。
foreach (int i in subList) {Console.WriteLine(i); }子列表集合的項目被打印到終端。
$ dotnet run 8 6 4 7 9 5大于 3 的整數(shù)列表中的值。
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#??計算素數(shù)
我們要計算素數(shù)。
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');在上面的示例中,我們處理了許多不同的運算符。素數(shù)(或素數(shù))是一個自然數(shù),它恰好有兩個不同的自然數(shù)除數(shù):1 和它自己。我們拿起一個數(shù)字并將其除以數(shù)字,從 1 到拾取的數(shù)字。實際上,我們不必嘗試所有較小的數(shù)字;我們可以除以數(shù)字,直到所選數(shù)字的平方根。該公式將起作用。我們使用余數(shù)除法運算符。
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 };我們根據(jù)這些數(shù)字計算素數(shù)。
if (num == 1) continue;By definition, 1 is not a prime
if (num == 2 || num == 3) {Console.Write(num + " ");continue; }我們跳過 2 和 3 的計算:它們是素數(shù)。請注意相等和條件或運算符的用法。 == 的優(yōu)先級高于 ||操作員。所以我們不需要使用括號。
int i = (int) Math.Sqrt(num);如果我們只嘗試小于所討論數(shù)字的平方根的數(shù)字,我們就可以了。數(shù)學(xué)證明,考慮到所討論數(shù)字的平方根的值就足夠了。
while (i > 1) {...i--; }這是一個while循環(huán)。 i 是計算得出的數(shù)字的平方根。我們使用遞減運算符在每個循環(huán)周期將 i 減一。當(dāng) i 小于 1 時,我們終止循環(huán)。例如,我們有數(shù)字 9。9 的平方根是 3。我們將 9 數(shù)字除以 3 和 2。
if (num % i == 0) {isPrime = false; }這是算法的核心。如果余數(shù)除法運算符為任何 i 值返回 0,則所討論的數(shù)字不是素數(shù)。
總結(jié)
以上是生活随笔為你收集整理的C#教程5:操作算子(2)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习:论相关(二)
- 下一篇: 时间序列:等分布序列(Equidistr