# C# Interview Questions ###### tags: `Tech Interview` `Job Hunt` ## C# vs .NET C# is a programming language while .NET is the framework used alongside C# to create a complete application. ## .NET Framework vs .NET Core vs .NET 5 - **.NET Framework:** Closed source, only ran on windows - **.NET Core:** Open source, cross platform - **.NET 5:** Unification of Framework with Core, alongside other runtimes such as Mono etc **Also,** - .NET Core an higher is superior in performance - **Reason:** DLLs and dependencies where split to smaller ones, only needed DLLs are loaded .Net Framework, less number of larger DLLs ![.Net Framework](https://i.imgur.com/fxxAPbB.png) .Net Core, more number of smalleer DLLs ![.Net Core](https://i.imgur.com/hmpXWAW.png) ## Compiling C# is compiled into IL (Intermediate language) first, then JIT (Just in Time) compiler compiles IL into machine language. **Why?:** Runtime environment might differ from development environment (different OS for example), hence, JIT chooses the best compile configuration depending on the runtime. ## CLR (Common Language Runtime) Main usages: 1. Invokes JIT to compile code into machine language 2. Cleans any unused objects using GC (garbage collector) ## GC (Garbage Collector) Keeps running in the background and claims any **unused and managed** resources. **Managed vs Non-Managed**: Managed is all the code that's written in C# (not imported as external DLLs for example) and is managed by the CLR. ## CTS (Common Type System) Ensures different data types accross different .NET programming languages are compiled to the same "common type". ## CLS (Common Language Spec) Is a specification where when followed, the program can be consumed by other programming language **Example:** Visual basic is not case sensitive, C# is **Spec:** Don't used two variable names of different cases ## Stack vs Heap #### Stack: - Stores value-type variables (primitives such as doubles, ints, booleans, etc) - Value is stored in the same place #### Heap: - Stores reference-type variables (objects) values refered to by a pointer - Value is pointed by pointer in stack ## Value Type vs Reference Type #### Value type: - Variable and Value are both stored in stack #### Reference type: - Variable stored in stack with a pointer, Value is stored in heap (pointed to by the pointer). ## Boxing vs UnBoxing - Boxing is moving data from value type to reference type (casting to an `object`) - UnBoxing is moving data from reference type to value type (casting to a primitive) ## Casting Converting data type **Implicit Casting**: Happens when moving from a lower datatype to higher datatype (no data loss) ```csharp int x = 10; double y = x; ``` > *See **Implicit Operators**..* **Explicit Casting**: Must happen when moving from a higher datatype to a lower datatype (with data loss). ```csharp double x = 10; int y = (int)x; ``` ## Collections | | Array | ArrayList | Collections (List) | | -------- | -------- | -------- | -------- | | Flexibility | Size is Constant | Variable in size | Variable in size | | Type Safety | Strongly typed | Object (boxing and unboxing) | Strongly typed (using generics) | | Notes | High Performance | Low performance due to boxing and unboxing + deprecated and should not be used in new code | Best of both worlds | ## TPL vs Threads - TPL is an abstraction over threads - TPL utilizes actual processor cores (without explicitly saying so) - TPL uses thread pool, and might eventually run on the same thread (with await/async) ## Abstract Classes vs Interfaces | Abstract Classes | Interfaces | | -------- | -------- | | "IS A" relationship | "HAS A" relationship | | Is inherited from | Is Implemented | | Allows "state" or fields | no fields | | Allows default implementation (virtual) | Allows default implementation | | Child class only allowed to inherit from one parent abstract class | Child class is allowed to implement multiple interfaces | ## Delegates **Type-Safe** Pointer to a function and are used for thread communications and callbacks #### Multicast Delegates: ![](https://i.imgur.com/MITDyp0.png) Note that when functions do have return values, multicast delegates will hold the value of the last function called ![](https://i.imgur.com/GZA251W.png) Same case with out parameters (result will be 2) ![](https://i.imgur.com/BoHVIo9.png) ## Func vs Action Both of them are forms of delegates - Func: Returns a value - Action: Doesn't return any values ## Events ```csharp delegate void MyEventHandler(object o, EventArgs args); event MyEventHandler MyEvent; ``` And then add method pointers (having the same signature as the handler) to MyEvent to subscribe to the event. OR ```csharp EventHandler<EventArgs> MyEvent; ``` ## SOLID - S. Single Responsibility Principle - `CLEAN CODE`: Module should only have a single reason to be modified later on. - O. Open for extension, closed for modification - When adding functionality, we should not modify existing modules, we should extend them - L. Liskov Substitution Principle - Objects of **Super Class** should be replaced with objects of **Sub Classes** without breaking the application - Objects of **SubClass** should behave the same as its **Super Class** - **BAD** EXAMPLE: ``` class Bird { Fly(); } ``` - `HummingBird` : `Bird` (Correct) - `Ostritch` : `Bird` (Not Correct) - **GOOD** EXAMPLE: ``` class Bird { } class FlyingBird { Fly(); } ``` - `HummingBird` : **`FlyingBird`** (Correct) - `Ostritch` : `Bird` (Correct) - I. Interface Segregation Principle - No class (client) should be forced to implement an irrelevant method (that would not be used). - **BAD** EXAMPLE: ``` interface IOrder { orderBurger(); orderFries(); } class BurgerOrder : IOrder // Forced to implement orderFries() class FriesOrder : IOrder // Forced to implement orderBurger() ``` - **GOOD** EXAMPLE: ``` interface IBurgerOrder { orderBurger(); } interface IFriesOrder { orderFries(); } class BurgerOrder : IBurgerOrder class FriesOrder : IFriesOrder ``` - D. Dependency Inversion - High level modules shouldn't depend on low level modules - High level modules **AND** low level modules should both depend **on abstractions** - Abstractions should not depend on details - Details should depend on abstractions - In other words, don't inject concretes, inject interfaces ``` // Wrong example: ElectricSwitch(LightBulb obj) ElectricSwitch(TV obj) ElectricSwitch(Fan obj) // Correct example ElectricSwitch(ISwitchable obj) // See this vid https://www.youtube.com/watch?v=9uubt7i_LGc ``` ### OOP - Inheritance - **Encapsulation**: hides variables or some implementation that may be changed so often in a class to prevent outsiders access it directly. They must access it via getter and setter methods. - **Abstraction**: is used to hide something too, but in a higher degree (class, interface). Clients who use an abstract class (or interface) do not care about what it was, they just need to know what it can do. ``` Encapsulation:-- Information hiding. Abstraction:-- Implementation hiding. ``` - Polymorphism - Objects are designed to share behaviors and they can take on more than one form. Polymorphism allows different types of objects to pass through the same interface (Array). ### Design Patterns - Creational - Builder: *Multisteps* - Factory **Method**: *Just a method that is called* - Abstract Factory: *Uses composition and dependency to construct a class* - Behavioural - Strategy - Structural - Adapter