Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

C# Dictionary

  1. Home
  2. C# Dictionary
  3. Operators (C#)

Operators (C#)

This page covers arithmetic, comparison, and logical operators in C#. C# provides a rich set of operators, with some behaviors that differ from other languages — such as integer division truncating the result and the + operator concatenating strings. Be sure to also understand how these operators interact with Nullable types and bitwise operations.

Arithmetic Operators

OperatorMeaningExampleResult
+Addition. Concatenation when used with strings.850 + 1501000
-Subtraction.850 - 50800
*Multiplication.850 * 21700
/Division. When both operands are integers, the result is also an integer (decimal part is truncated).850 / 4212
%Remainder (modulo).850 % 73
++Increment. Increases the value by 1.level++level + 1
--Decrement. Decreases the value by 1.level--level - 1

When both operands of / are integers, the result is also an integer. For example, 850 / 4 produces 212, not 212.5. If you need a floating-point result, cast one of the operands to double or float (e.g., (double)850 / 4).

The + operator on string performs string concatenation. When you join a number and a string with +, the number is automatically converted to a string and concatenated (e.g., "Score: " + 850"Score: 850").

Comparison Operators

OperatorMeaningExampleResult
==Equal to.score == 850true / false
!=Not equal to.score != 0true / false
>Greater than.score > 850true / false
>=Greater than or equal to.score >= 850true / false
<Less than.score < 850true / false
<=Less than or equal to.score <= 850true / false

All comparison operators return a bool value (true or false). For string, the == operator compares by value (content), not by reference. This is because C#'s string overloads the == operator, so you do not need a special method like Java's .equals().

Logical Operators

OperatorMeaningDescription
&&Logical ANDReturns true when both the left and right operands are true. If the left operand is false, the right operand is not evaluated (short-circuit evaluation).
||Logical ORReturns true when either the left or right operand is true. If the left operand is true, the right operand is not evaluated (short-circuit evaluation).
!Logical NOTInverts the value: true becomes false, and false becomes true.

&& and || use short-circuit evaluation. With &&, evaluation stops as soon as the left operand is false. With ||, evaluation stops as soon as the left operand is true. This behavior is commonly used to perform a null check first and then safely access a member (e.g., obj != null && obj.IsValid).

Bitwise Operators

OperatorMeaningExampleResult (binary)
&Bitwise AND0b1010 & 0b11000b1000 (8)
|Bitwise OR0b1010 | 0b11000b1110 (14)
^Bitwise XOR0b1010 ^ 0b11000b0110 (6)
~Bitwise NOT~0b00000001All bits inverted.
<<Left shift1 << 38 (2³)
>>Right shift8 >> 14

Bitwise operators are primarily used for flag management (combining the [Flags] attribute with enum) and low-level processing where performance matters. In game development, they are useful for managing multiple state flags packed into a single integer.

Nullable Types and Operators

When using arithmetic or comparison operators with Nullable types such as int?, be careful: if a Nullable variable is null, arithmetic operations on it also produce null. For comparisons, any comparison with null always returns false, so use == null or is null to check for null.

int? hp = null;

// Applying arithmetic operators to null propagates null.
int? result = hp + 100; // result is null.

// Use the null-coalescing operator to provide a default value.
int actualHp = hp ?? 0; // If hp is null, use 0.

// Use == null or is null for null checks.
if (hp == null) {
	// Code to run when hp is null.
}

Sample Code

ArithmeticOperators.cs
using System;

class ArithmeticOperators {
	static void Main() {

		int scoreA = 850; // Base score.
		int bonus = 150; // Bonus points.

		Console.WriteLine("=== Arithmetic Operators: Basics ===");
		Console.WriteLine("Addition (+): " + (scoreA + bonus)); // 1000
		Console.WriteLine("Subtraction (-): " + (scoreA - bonus)); // 700
		Console.WriteLine("Multiplication (*): " + (scoreA * 2)); // 1700
		Console.WriteLine("Remainder (%): " + (scoreA % 7)); // Remainder of 850 divided by 7.

		// When dividing two integers, the decimal part is truncated.
		Console.WriteLine("\n=== Integer Division ===");
		int intDiv = scoreA / 4; // Integer division: 212 (no decimal).
		double doubleDiv = (double)scoreA / 4; // Cast to double for floating-point division: 212.5.
		Console.WriteLine("int / int: " + intDiv); // 212
		Console.WriteLine("double / int: " + doubleDiv); // 212.5

		// The difference appears when the result is not evenly divisible.
		int intRemainder = 850 / 7; // 121 (0.42... is truncated).
		double doubleRemainder = (double)850 / 7; // 121.4285...
		Console.WriteLine("850 / 7 (int): " + intRemainder); // 121
		Console.WriteLine("850 / 7 (double): " + doubleRemainder); // 121.42857142857143

		Console.WriteLine("\n=== Increment / Decrement ===");
		int level = 1;
		Console.WriteLine("Initial level: " + level); // 1

		level++; // Postfix increment: adds 1 after the expression is evaluated.
		Console.WriteLine("After level++: " + level); // 2

		++level; // Prefix increment: adds 1 before the expression is evaluated.
		Console.WriteLine("After ++level: " + level); // 3

		level--; // Postfix decrement: subtracts 1 after the expression is evaluated.
		Console.WriteLine("After level--: " + level); // 2

		// The difference between prefix and postfix matters inside an expression.
		int a = 5;
		int b = a++; // b gets the value before the increment (5); a becomes 6.
		Console.WriteLine("a = " + a + ", b = " + b); // a=6, b=5

		int c = 5;
		int d = ++c; // d gets the value after the increment (6); c also becomes 6.
		Console.WriteLine("c = " + c + ", d = " + d); // c=6, d=6

		// When you join a number and a string with +, the number is automatically converted to a string.
		Console.WriteLine("\n=== The + Operator with Strings ===");
		string name = "item_a";
		int score = 850;
		string msg = name + "'s score is " + score + "."; // The number is converted to a string.
		Console.WriteLine(msg); // item_a's score is 850.

		Console.WriteLine("Total: " + (score + 150)); // Total: 1000 (numeric addition).
		Console.WriteLine("Total: " + score + 150); // Total: 850150 (string concatenation).
	}
}

This produces the following output:

dotnet script ArithmeticOperators.cs
=== Arithmetic Operators: Basics ===
Addition (+): 1000
Subtraction (-): 700
Multiplication (*): 1700
Remainder (%): 3

=== Integer Division ===
int / int: 212
double / int: 212.5
850 / 7 (int): 121
850 / 7 (double): 121.42857142857143

=== Increment / Decrement ===
Initial level: 1
After level++: 2
After ++level: 3
After level--: 2
a = 6, b = 5
c = 6, d = 6

=== The + Operator with Strings ===
item_a's score is 850.
Total: 1000
Total: 850150
ComparisonLogicalOperators.cs
using System;

class ComparisonLogicalOperators {
	static void Main() {

		int scoreA = 850; // Score A.
		int scoreB = 720; // Score B.
		int scoreC = 930; // Score C.

		Console.WriteLine("=== Comparison Operators ===");
		Console.WriteLine("scoreA == scoreB: " + (scoreA == scoreB)); // False
		Console.WriteLine("scoreA != scoreB: " + (scoreA != scoreB)); // True
		Console.WriteLine("scoreA >  scoreB: " + (scoreA > scoreB)); // True
		Console.WriteLine("scoreA >= scoreC: " + (scoreA >= scoreC)); // False
		Console.WriteLine("scoreA <  scoreC: " + (scoreA < scoreC)); // True
		Console.WriteLine("scoreA <= scoreC: " + (scoreA <= scoreC)); // True

		Console.WriteLine("\n=== String Comparison ===");
		string name1 = "item_a";
		string name2 = "item_a"; // A separate string variable with the same content.
		string name3 = "item_b";

		Console.WriteLine("name1 == name2: " + (name1 == name2)); // True (same content).
		Console.WriteLine("name1 == name3: " + (name1 == name3)); // False (different content).

		Console.WriteLine("\n=== Logical Operators ===");

		bool isActive = true; // Whether the item is active.
		bool hasBoost = true; // Whether the item has a boost.
		bool hasOption = false; // Whether the item has an option enabled.

		// && (AND): returns true only when both operands are true.
		bool optionEnabled = isActive && hasOption;
		Console.WriteLine("Option enabled (isActive && hasOption): " + optionEnabled); // False

		// || (OR): returns true when at least one operand is true.
		bool isStrong = isActive || hasBoost;
		Console.WriteLine("Is effective (isActive || hasBoost): " + isStrong); // True

		// ! (NOT): inverts the value.
		bool isInactive = !isActive;
		Console.WriteLine("Is inactive (!isActive): " + isInactive); // False

		Console.WriteLine("\n=== Compound Conditions ===");

		// Determines whether the item passes (compound condition example).
		int threshold = 900; // Minimum score required to pass.
		bool passes = isActive && (scoreA >= threshold || hasBoost);
		Console.WriteLine("Passes (isActive && (score sufficient || hasBoost)): " + passes); // True

		// &&: if the left operand is false, the right operand is not evaluated.
		// ||: if the left operand is true, the right operand is not evaluated.
		Console.WriteLine("\n=== Short-Circuit Evaluation ===");

		// Safe member access pattern combined with a null check.
		string targetName = "item_x";
		bool hasLongName = targetName != null && targetName.Length > 3;
		// If targetName is null, targetName.Length is never evaluated, so no NullReferenceException is thrown.
		Console.WriteLine("Name is longer than 3 characters: " + hasLongName); // True (6 characters).

		// When null, short-circuit evaluation skips the right operand.
		string nullName = null;
		bool isNullLong = nullName != null && nullName.Length > 3;
		Console.WriteLine("null name is longer than 3 characters: " + isNullLong); // False (right side not evaluated).
	}
}

This produces the following output:

dotnet script ComparisonLogicalOperators.cs
=== Comparison Operators ===
scoreA == scoreB: False
scoreA != scoreB: True
scoreA >  scoreB: True
scoreA >= scoreC: False
scoreA <  scoreC: True
scoreA <= scoreC: True

=== String Comparison ===
name1 == name2: True
name1 == name3: False

=== Logical Operators ===
Option enabled (isActive && hasOption): False
Is effective (isActive || hasBoost): True
Is inactive (!isActive): False

=== Compound Conditions ===
Passes (isActive && (score sufficient || hasBoost)): True

=== Short-Circuit Evaluation ===
Name is longer than 3 characters: True
null name is longer than 3 characters: False
NullableOperators.cs
using System;

class NullableOperators {
	static void Main() {

		// int? is an integer type that can also hold null.
		int? valueA = 1000; // Value A (has a value).
		int? valueB = null; // Value B (unknown, so null).

		Console.WriteLine("=== Nullable Types and Arithmetic Operators ===");

		// Arithmetic operators on Nullable types propagate null.
		int? resultA = valueA + 500; // Normal calculation when a value exists.
		int? resultB = valueB + 500; // Arithmetic on null produces null.
		Console.WriteLine("valueA + 500 = " + resultA); // 1500
		Console.WriteLine("valueB + 500 = " + resultB); // (blank: null)

		Console.WriteLine("\n=== Null-Coalescing Operator (??) ===");
		int actualB = valueB ?? 0; // Use 0 if valueB is null.
		Console.WriteLine("valueB ?? 0 = " + actualB); // 0

		int actualA = valueA ?? 0; // valueA is not null, so it is used as-is.
		Console.WriteLine("valueA ?? 0 = " + actualA); // 1000

		Console.WriteLine("\n=== Nullable Type Comparisons ===");

		// Use == null or is null to check for null.
		Console.WriteLine("valueB == null: " + (valueB == null)); // True
		Console.WriteLine("valueB is null: " + (valueB is null)); // True
		Console.WriteLine("valueA == null: " + (valueA == null)); // False

		// Comparisons such as > and < against null always return false.
		Console.WriteLine("null > 0:  " + (valueB > 0)); // False
		Console.WriteLine("null < 0:  " + (valueB < 0)); // False
		Console.WriteLine("null == 0: " + (valueB == 0)); // False (null is not equal to 0).

		Console.WriteLine("\n=== Bitwise Operators for Flag Management ===");

		// Managing state flags with bits.
		const int FLAG_A = 0b0001; // Flag A.
		const int FLAG_B = 0b0010; // Flag B.
		const int FLAG_C = 0b0100; // Flag C.
		const int FLAG_D = 0b1000; // Flag D.

		int flags = FLAG_A | FLAG_B | FLAG_C; // Set multiple flags with OR.
		Console.WriteLine("Flags: " + flags); // 7 (0111)

		bool hasA = (flags & FLAG_A) != 0;
		bool hasD = (flags & FLAG_D) != 0;
		Console.WriteLine("FLAG_A: " + hasA); // True
		Console.WriteLine("FLAG_D: " + hasD); // False

		// Add a flag using OR.
		flags |= FLAG_D;
		Console.WriteLine("Flags after adding FLAG_D: " + flags); // 15 (1111)

		// Remove a flag using AND NOT.
		flags &= ~FLAG_B;
		Console.WriteLine("Flags after removing FLAG_B: " + flags); // 13 (1101)
	}
}

This produces the following output:

dotnet script NullableOperators.cs
=== Nullable Types and Arithmetic Operators ===
valueA + 500 = 1500
valueB + 500 =

=== Null-Coalescing Operator (??) ===
valueB ?? 0 = 0
valueA ?? 0 = 1000

=== Nullable Type Comparisons ===
valueB == null: True
valueB is null: True
valueA == null: False
null > 0:  False
null < 0:  False
null == 0: False

=== Bitwise Operators for Flag Management ===
Flags: 7
FLAG_A: True
FLAG_D: False
Flags after adding FLAG_D: 15
Flags after removing FLAG_B: 13

Common Mistakes

Expecting a decimal from integer division

The result of int / int is int. The decimal part is truncated, so 9 / 2 produces 4, not 4.5. Cast at least one operand to double when you need a floating-point result.

int a = 9;
int b = 2;

int wrong = a / b;
Console.WriteLine(wrong); // 4 (decimal part truncated)

double correct = (double)a / b;
Console.WriteLine(correct); // 4.5

String + number concatenation instead of addition

Writing "Result: " + a + b converts both a and b to strings before concatenating, so no numeric addition occurs. Wrap the addition in parentheses to add the numbers first.

int x = 100;
int y = 200;

Console.WriteLine("Total: " + x + y);     // Total: 100200 (string concatenation)
Console.WriteLine("Total: " + (x + y));   // Total: 300 (numeric addition)

Summary

The most important thing to watch out for with C# operators is integer division. When both operands of / are int, the result is also an int and the decimal part is always truncated. 9 / 2 produces 4, not 4.5. If you need a floating-point result, cast explicitly using (double)a / b.

The + operator on string performs string concatenation. Writing Console.WriteLine("Total: " + a + b) performs string concatenation, not numeric addition. To add the numbers first, wrap them in parentheses: "Total: " + (a + b).

Taking advantage of short-circuit evaluation in && and || lets you safely access properties or methods after a null check. Note that & and | (bitwise operators) also work on bool, but they do not short-circuit, so use && and || for normal conditional logic.

Arithmetic operations on Nullable types (such as int?) propagate null. Either provide a default value with the null-coalescing operator (null ?? 0), or check for null using the HasValue property before performing the calculation. For more on Nullable types, see Nullable Types. For more on the null-coalescing operator, see Null-Coalescing Operator (??).

If you find any errors or copyright issues, please .