Bir operatör bir, iki ya da üç işlenen alır ve bir değer üretir: a + b, !done, x ?? fallback. C#'ın operatörleri C, Java ve JavaScript'inkilere yakındır, ama birkaçı yeni başlayanları şaşırtan biçimlerde davranır; özellikle tamsayı bölmesi ve %'nin işareti.
Aritmetik operatörler
+, -, *, / ve % her sayısal tipte çalışır. Sonucun tipi işlenenleri izler: iki int değeri bir int, bir int ile bir double bir double üretir.
Çıktı:
22
12
85
3
2
3.4
3.4
3
3.4
Tamsayı bölmesi sıfıra doğru keser. 17 / 5 3, -17 / 5 ise -3'tür. Bu çok yaygın bir hataya yol açar: int percent = done / total * 100; done < total olduğunda her zaman 0'dır, çünkü done / total zaten 0'dır. Önce çarpın (done * 100 / total) ya da double olarak bölün.
Bir tamsayıyı ya da decimal'i sıfıra bölmek DivideByZeroException fırlatır. Bir double'ı sıfıra bölmek istisna fırlatmaz; sonsuz ya da 0.0 / 0.0 için NaN üretir:
Çıktı:
True
True
False
DivideByZeroException
Mod operatörü ve negatif sayılar
% bölmenin kalanını döndürür ve sonucu sol işlenenin işaretini alır. Bu, pozitif bir bölen için her zaman negatif olmayan Python'dan ve matematikteki "mod"dan farklıdır:
Çıktı:
1
-1
1
2
even
62 min 5 s
Thu
1.5
Sol taraf negatif olabiliyorsa ve sonuç bir indeksse Mod yardımcısını kullanın: days[(today + offset) % 7] negatif bir toplam için IndexOutOfRangeException fırlatırdı. Tek sayı testi de aynı tuzağa sahiptir: n % 2 == 1 negatif tek sayılar için false'tur; n % 2 != 0 testini yapın.
Atama, bileşik atama ve artırma
= atar. Bileşik biçimler +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= bir işlemi atamayla birleştirir. ++ ve -- 1 ekler ya da çıkarır ve döndürdükleri değerde farklılaşan önek ve sonek biçimlerinde gelir:
Çıktı:
14
start, step
a=5 b=7 i=7
4
byte örneği bir tuhaflığı gösterir: level = level + 10; derlenmez, çünkü byte + int bir int'tir; ama level += 10; derlenir, çünkü bileşik atama değişkenin tipine örtük bir cast içerir. Bu cast taşmada başa sarar (250 + 10, 4 olur).
Karşılaştırma ve mantıksal operatörler
Karşılaştırma operatörleri (==, !=, <, >, <=, >=) bir bool döndürür. String'ler için == referansları değil metni karşılaştırır. Mantıksal operatörler ! (değil), && (ve), || (veya) ve ^ (özel veya) şeklindedir.
Çıktı:
True
no active user
with ||:
evaluated A
with |:
evaluated A
evaluated B
True
&& ve || kısa devre yapar: sağ işlenen yalnızca sonucu değiştirebilecekse çalışır. user != null && user.IsActive ifadesini güvenli yapan budur. Boolean'larda tek & ve | her zaman iki tarafı da değerlendirir; bu bir koşulda nadiren istenen şeydir.
Bitsel ve kaydırma operatörleri
Tamsayı tiplerinde &, |, ^ ve ~ tek tek bitler üzerinde çalışır, << ve >> onları kaydırır. Bayraklar, maskeler, hash hesaplama ve düşük seviye protokoller için kullanılırlar:
Çıktı:
3
True
False
101
1024
125
5
-1
Adlandırılmış bayrak kümeleri için [Flags] özniteliğine sahip bir enum, tamsayı sabitlerinden daha anlaşılırdır ve HasFlag bir maskeden daha iyi okunur. C# 11, negatif sayılar için bile sıfırlarla dolduran işaretsiz sağa kaydırma >>>'ı ekledi.
Null operatörleri
null olabilen değerlerle çalışmak için üç operatör vardır:
Çıktı:
Guest
0
5
a ?? b, null değilse a'yı, null ise b'yi döndürür. a?.Member, a null olduğunda istisna fırlatmak yerine null döndürür. C# 8, yalnızca a null olduğunda a'ya b'yi atayan a ??= b'yi ekledi. Bunlar nullable tipler sayfasında ayrıntılı ele alınır.
Operatör önceliği
Bir ifade operatörleri karıştırdığında üst satırlar daha sıkı bağlanır. Aynı satırdaki operatörler soldan sağa gruplanır; atama, ?? ve ?: ise sağdan sola gruplanır. (İşlenenlerin kendileri her zaman soldan sağa değerlendirilir.)
| Kategori | Operatörler |
|---|---|
| Birincil | x.y, x?.y, f(x), a[i], x++, x--, new, typeof, nameof |
| Tekli | +x, -x, !x, ~x, ++x, --x, (T)x, await |
| Çarpımsal | *, /, % |
| Toplamsal | +, - |
| Kaydırma | <<, >>, >>> |
| İlişkisel ve tip testi | <, >, <=, >=, is, as |
| Eşitlik | ==, != |
| Bitsel VE | & |
| Bitsel XOR | ^ |
| Bitsel VEYA | | |
| Koşullu VE | && |
| Koşullu VEYA | || |
| Null birleştirme | ?? |
| Koşullu | c ? a : b |
| Atama ve lambda | =, +=, -=, ??=, => ve diğer bileşik biçimler |
Bilmeye değer iki sonuç: a + b * c önce çarpar ve x & mask == 0 önce karşılaştırır (==, &'den daha sıkı bağlanır), yani x & (mask == 0) anlamına gelir ve tamsayılar için derlenmez. (x & mask) == 0 yazın. Parantezlerin hiçbir maliyeti yoktur ve niyeti açıkça gösterir.
Operatör aşırı yükleme
Kendi tipleriniz operatörlerin ne anlama geldiğini tanımlayabilir. decimal, DateTime ve TimeSpan'in + ve <'yi desteklemesi böyledir:
Çıktı:
33.49
True
Operatörler public static olmalıdır ve bazıları zorunlu çiftler halinde gelir: < tanımlamak > gerektirir, == de != gerektirir. == tanımlandığında derleyici, eşleşecek şekilde Equals ve GetHashCode'u override edene kadar uyarı da verir. Operatörleri yalnızca anlamın açık olduğu yerlerde aşırı yükleyin; sayılar, vektörler ve para gibi.
Sıkça Sorulan Sorular
C#'ta % ne yapar?
% kalan operatörüdür: 17 % 5 2'dir. Sonuç sol işlenenin işaretini alır, bu yüzden -7 % 3 Python'daki gibi 2 değil -1'dir. Bir indeksi başa sararken gerektiği gibi her zaman negatif olmayan bir sonuç için ((a % n) + n) % n yazın. double ve decimal üzerinde de çalışır: 7.5 % 2 1.5'tir.
C#'ta 7 / 2 neden 3 eder?
İki işlenen de tamsayı olduğunda / tamsayı bölmesi yapar ve kesirli kısmı atar, sıfıra doğru keser. Kesirli bir sonuç almak için işlenenlerden birini kayan noktalı ya da decimal bir değer yapın: 7 / 2.0 3.5'tir, (double)a / b bölmeden önce dönüştürür ve 7m / 2 bir decimal olarak 3.5'tir.
C#'ta && ile & arasındaki fark nedir?
&& koşullu VE'dir: sol taraf false ise sağ taraf değerlendirilmez. Boolean'larda & her zaman iki tarafı da değerlendirir, tamsayılarda ise bitsel VE'dir. Koşullar için && ve || kullanın, özellikle & ile bir NullReferenceException fırlatacak olan user != null && user.IsActive gibi korumalarda.
C#'ta i++ ile ++i arasındaki fark nedir?
İkisi de i'ye 1 ekler. i++ ifadesi eski değeri, ++i yeni değeri verir. Tek başına bir satırda (i++;) fark yoktur. Yalnızca sonuç kullanıldığında önemlidir, örneğin int a = i++;; birçok stil kılavuzunun artırmaları kendi satırlarında tutmasının nedeni budur.
C#'ta operatör önceliği nedir?
En yüksekten en düşüğe: birincil (x.y, f(x), a[i], x++), tekli (!, -, ++x, cast'ler), çarpımsal (* / %), toplamsal (+ -), kaydırmalar, ilişkisel (< > <= >= is as), eşitlik (== !=), &, ^, |, &&, ||, ??, koşullu ?: ve son olarak atama. Emin değilseniz parantez ekleyin.