What is C# and how is it related to .NET?
C# is a statically typed, object-oriented language from Microsoft. The compiler turns it into IL (intermediate language), and the .NET runtime (the CLR) compiles that IL to machine code when the program runs. .NET is the platform around the language: the runtime, the base class library and the SDK. More in What is C#.
What are the built-in data types in C#?
C# has value types for numbers, characters and booleans (
int,long,double,decimal,bool,char), plusstringandobjectas built-in reference types. Each keyword aliases a .NET type:intisSystem.Int32. Usedecimalfor money.C#using System; class Program { static void Main() { Console.WriteLine(sizeof(int) + " " + sizeof(long) + " " + sizeof(decimal) + " " + sizeof(char)); Console.WriteLine(int.MaxValue); Console.WriteLine(typeof(int).FullName); } }Trap:
charis 2 bytes, one UTF-16 code unit, not a byte as in C.What is the difference between
stringandStringin C#?There is no difference:
stringis the C# keyword forSystem.String, and both compile to the same IL, as dointandInt32. Use the keyword in declarations.Stringneedsusing System;;stringnever does.What do
7 / 2and7 / 2.0evaluate to in C#?C#using System; class Program { static void Main() { Console.WriteLine(7 / 2 + " " + 7 / 2.0 + " " + 7 % 3); } }7 / 2divides twointvalues, so the fraction is dropped:3. With onedoubleoperand (2.0) the division is floating point:3.5.7 % 3is the remainder,1.For an average, cast first:
(double)sum / count, not(double)(sum / count), which has already truncated.What is
i++ + ++iwhenistarts at 5?C#using System; class Program { static void Main() { int i = 5; Console.WriteLine(i++ + ++i); } }C# evaluates operands left to right, so the result is defined (in C it is undefined behavior).
i++yields5and setsito 6;++isetsito 7 and yields7. The sum is12.What is the difference between
constandreadonlyin C#?A
constis a compile-time constant, implicitlystatic, limited to numbers,bool,char,string, enums andnull. Areadonlyfield can be any type and is set once at run time, in its declaration or a constructor.class Config { public const int MaxUsers = 100; // baked into callers at compile time public static readonly DateTime Started = DateTime.Now; // computed at runtime public readonly Guid Id; public Config() { Id = Guid.NewGuid(); } // readonly can be set here }Trap: a
public constis copied into every assembly that uses it, so callers keep the old value until they are recompiled. Usestatic readonlyfor values that might change.What is the difference between
refandoutparameters?Both pass a variable by reference. A
refargument must be initialized before the call; anoutparameter need not be, but the method must assign it before returning.C#using System; class Program { static void Double(ref int x) { x *= 2; } static bool TryHalf(int n, out int half) { half = n / 2; return n % 2 == 0; } static void Main() { int value = 21; Double(ref value); Console.WriteLine(value); if (TryHalf(value, out int h)) Console.WriteLine("half is " + h); } }outis the pattern behindint.TryParse. See ref and out.What are tuples in C#, and how do you return multiple values from a method?
C# 7 tuples (
System.ValueTuple) group a few values without declaring a type, such as(int min, int max), and are the usual way to return several values from a private method.C#using System; class Program { static (int min, int max) MinMax(int[] nums) { int min = nums[0], max = nums[0]; foreach (int n in nums) { if (n < min) min = n; if (n > max) max = n; } return (min, max); } static void Main() { var r = MinMax(new[] { 4, 9, 1, 7 }); Console.WriteLine(r.min + " " + r.max); var (lo, hi) = MinMax(new[] { 3, 8 }); // deconstruction Console.WriteLine(lo + " " + hi); int a = 1, b = 2; (a, b) = (b, a); // swap without a temp variable Console.WriteLine(a + " " + b); } }Trap: the element names exist only at compile time; at run time the fields are
Item1,Item2. See tuples.Does
==compare strings by value or by reference in C#?C#using System; class Program { static void Main() { string a = "hello"; string b = new string("hello".ToCharArray()); Console.WriteLine((a == b) + " " + ((object)a == (object)b) + " " + a.Equals(b)); } }==on twostringvariables is overloaded to compare characters:True. Cast toobject,==compares references, andnew string(...)made a second object:False.Equalsis virtual andStringoverrides it to compare values:True.==is chosen at compile time from the static types.Why are strings immutable in C#, and when should you use StringBuilder?
A
stringnever changes after it is created;+,ReplaceandToUpperreturn new strings, which makes strings safe to share between threads. UseStringBuilderto build a string in a loop, because it appends into one buffer instead of copying the whole text each step.C#using System; using System.Text; class Program { static void Main() { string s = "abc"; string t = s.ToUpper(); Console.WriteLine(s + " " + t); var sb = new StringBuilder(); for (int i = 1; i <= 5; i++) sb.Append(i).Append(','); sb.Length--; // drop the last comma Console.WriteLine(sb.ToString()); } }See StringBuilder.
What is boxing and unboxing in C#?
Boxing copies a value type into a new heap object so it can be used as
objector an interface; unboxing copies it back out with a cast. Both cost time in hot loops.C#using System; class Program { static void Main() { int n = 42; object boxed = n; // boxing: new object on the heap int back = (int)boxed; // unboxing: type check and copy Console.WriteLine(back); try { long wrong = (long)boxed; // must unbox to the exact type Console.WriteLine(wrong); } catch (InvalidCastException) { Console.WriteLine("InvalidCastException"); } } }Trap: unboxing must use the exact boxed type, so a boxed
intbecomes alongwith(long)(int)boxed.Are two boxed ints equal under
==? And underEquals?C#using System; class Program { static void Main() { object a = 1; object b = 1; Console.WriteLine((a == b) + " " + a.Equals(b)); } }Each assignment boxes the
1into a separate object.==on twoobjectvariables compares references:False.Equalsis virtual, and the boxedInt32compares values:True. Compare values that travel asobjectwithEquals.What are nullable types, and what do
?,??and?.do?int?(Nullable<int>) is a value type that can also holdnull.??returns the right side when the left side is null;?.calls a member only on a non-null object and givesnullotherwise.C#using System; class Program { static void Main() { int? age = null; Console.WriteLine(age.HasValue); Console.WriteLine(age ?? 18); string name = null; int? length = name?.Length; Console.WriteLine(length == null); Console.WriteLine(name?.Length ?? 0); } }Trap:
.Valueon a nullint?throwsInvalidOperationException. See nullable types.What is the difference between
var,dynamicandobject?varlets the compiler infer the static type, so the variable stays strongly typed.objectis the base type of everything and needs casts.dynamicskips compile-time checks and resolves members at run time.var count = 10; // count is an int; count = "x" does not compile object o = 10; // int boxed as object; o + 1 does not compile int n = (int)o + 1; // a cast is needed dynamic d = 10; d = d + 1; // resolved at runtime d.Foo(); // compiles, throws RuntimeBinderException when runUse
dynamiconly for COM interop or truly dynamic data.What are the access modifiers in C#?
C# has six access levels; the defaults are
privatefor class and struct members andinternalfor top-level types. C# 11 also addsfile, which limits a top-level type to its source file (see access modifiers).Modifier Accessible from publicanywhere privatethe same class protectedthe class and derived classes internalthe same assembly protected internalsame assembly or derived classes private protectedderived classes in the same assembly Trap:
internalmeans the assembly, not the namespace.What happens when you add 1 to
int.MaxValuein C#?C#using System; class Program { static void Main() { int x = int.MaxValue; x++; Console.WriteLine(x); } }Integer arithmetic is unchecked by default (unless the project sets
CheckForOverflowUnderflow), so adding 1 toint.MaxValuewraps toint.MinValue,-2147483648, with no exception. Acheckedblock orchecked(x + 1)throwsOverflowExceptioninstead. A constant expression such asint.MaxValue + 1is a compile error.In what order do a
returnintryand itsfinallyblock run?C#using System; class Program { static int F() { try { return 1; } finally { Console.Write("finally "); } } static void Main() { Console.WriteLine(F()); } }finallyruns whenever control leaves thetryblock, including throughreturn. The value1is computed,finallywritesfinally, and then the method returns, soMainprints1after it. Areturninsidefinallyis a compile error in C#.
C# Basics Interview Questions
Types, operators, strings, nullable values and exceptions, the basics of every campus and junior round.