C# Fundamentals
Inversion of Control
A design principle that allows the creation of new objects to be made without coupling. It removes dependencies from the code. It transfers control of the object to a container or framework
Anonymous method
As the name suggests, an anonymous method is a method without a name. Anonymous methods in C# can be defined using the delegate keyword and can be assigned to a variable of delegate type.
String
In C#, a string is a collection or an array of characters. So, string can be created using a char array or accessed like a char array.
Implicitly Typed Local Variable
C# 3.0 introduced var keyword to declare method level variables without specifying a data type explicitly. Ex. var j = 100; // implicitly typed local variable Notes: 1. Implicitly-typed variables must be initialized at the time of declaration; otherwise C# compiler would give an error: Implicitly-typed variables must be initialized. 2. Multiple declarations of var variables in a single statement are not allowed. 3. var cannot be used for function parameters. 4. var can also be used with LINQ queries.
C# Class
In object-oriented programming, a class defines some properties, fields, events, methods, etc. A class defines the kinds of data and the functionality their objects will have. A class enables you to create your custom types by grouping variables of other types, methods, and events.
Reference Type
Unlike value types, a reference type doesn't store its value directly. Instead, it stores the address where the value is being stored. In other words, a reference type contains a pointer to another memory location that holds the data. Reference type stores the address of the location where the actual value is stored instead of the value itself. When you pass a reference type variable from one method to another, it doesn't create a new copy; instead, it passes the variable's address. So, If we change the value of a variable in a method, it will also be reflected in the calling method. Examples: String Arrays (even if their elements are value types) Class Delegate
Scientific Notation
Use e or E to indicate the power of 10 as exponent part of scientific notation with float, double or decimal. Ex. double d = 0.12e2; Console.WriteLine(d); // 12;
Func Delegate
C# includes built-in generic delegate types Func and Action, so that you don't need to define custom delegates manually in most cases. Func is a generic delegate included in the System namespace. It has zero or more input parameters and one out parameter. The last parameter is considered as an out parameter. The Func delegate that takes one input parameter and one out parameter is defined in the System namespace
Floating Point Types
Floating-point numbers are positive or negative numbers with one or more decimal points. C# includes three data types for floating-point numbers: float, double, and decimal.
C# Enumerations Type - Enum
In C#, an enum (or enumeration type) is used to assign constant names to a group of numeric integer values. It makes constant values more readable, for example, WeekDays.Monday is more readable then number 0 when referring to the day in a week. An enum is defined using the enum keyword, directly inside a namespace, class, or structure. All the constant names can be declared inside the curly brackets and separated by a comma. If values are not assigned to enum members, then the compiler will assign integer values to each member starting with zero by default. The first member of an enum will be 0, and the value of each successive enum member is increased by 1.
What is .Net?
.NET is a free, cross-platform, open source developer platform for building many different types of applications. With .NET, you can use multiple languages, editors, and libraries to build for web, mobile, desktop, games, and IoT. https://dotnet.microsoft.com/learn/dotnet/what-is-dotnet
Value Type
A data type is a value type if it holds a data value within its own memory space. It means the variables of these data types directly contain values. When you pass a value-type variable from one method to another, the system creates a separate copy of a variable in another method. If value got changed in the one method, it wouldn't affect the variable in another method. Examples: bool byte char decimal double enum float int long sbyte short struct uint ulong ushort
Jagged Array
A jagged array is an array of array. Jagged arrays store arrays instead of literal values. A jagged array is initialized with two square brackets [][]. The first bracket specifies the size of an array, and the second bracket specifies the dimensions of the array which is going to be stored.
Constructor
A method for creating an object in a class. A class can have parameterized or parameterless constructors. The constructor will be called when you create an instance of a class. Constructors can be defined by using an access modifier and class name: <access modifiers> <class name>(){ }
C# Method
A method is a code block that contains a series of statements. A method can be defined using the following template: {access modifier} {return type} MethodName({parameterType parameterName})
Property
A property can be defined using getters and setters. Property encapsulates a private field. It provides getters (get{}) to retrieve the value of the underlying field and setters (set{}) to set the value of the underlying field.
Dependency Injection
A technique for achieving Inversion of Control (IoC) between classes and their dependencies. It allows the creation of dependent objects outside of a class and provides those objects to a class through different ways. Using DI, we move the creation and binding of the dependent objects outside of the class that depends on them. The Dependency Injection pattern involves 3 types of classes. Client Class: The client class (dependent class) is a class which depends on the service class Service Class: The service class (dependency) is a class that provides service to the client class. Injector Class: The injector class injects the service class object into the client class. Types of DI: Constructor Injection: In the constructor injection, the injector supplies the service (dependency) through the client class constructor. Property Injection: In the property injection (aka the Setter Injection), the injector supplies the dependency through a public property of the client class. Method Injection: In this type of injection, the client class implements an interface which declares the method(s) to supply the dependency and the injector uses this interface to supply the dependency to the client class.
Special Characters
A text in the real world can include any character. In C#, because a string is surrounded with double quotes, it cannot include " in a string. The following will give a compile-time error. C# includes escaping character \ (backslash) before these special characters to include in a string. Ex. string text = "This is a \"string\" in C#."; However, it will be very tedious to prefix \ for every special character. Prefixing the string with an @ indicates that it should be treated as a literal and should not escape any character. Ex. string str = @"xyzdef\rabc";
Access Modifiers
Access modifiers are applied to the declaration of the class, method, properties, fields, and other members. They define the accessibility of the class and its members. Public, private, protected, and internal are access modifiers in C#.
Action Delegate
Action is a delegate type defined in the System namespace. An Action type delegate is the same as Func delegate except that the Action delegate doesn't return a value. In other words, an Action delegate can be used with a method that has a void return type.
Array
An array is the data structure that stores a fixed number of literal values (elements) of the same data type. Array elements are stored contiguously in the memory. In C#, an array can be of three types: single-dimensional, multidimensional, and jagged array. Array elements can be accessed using an index. An index is a number associated with each array element, starting with index 0 and ending with array size - 1. Use the for loop to access array elements. Use the length property of an array in conditional expression of the for loop.
Events
An event is a notification sent by an object to signal the occurrence of an action. Events in .NET follow the observer design pattern. The class who raises events is called Publisher, and the class who receives the notification is called Subscriber. There can be multiple subscribers of a single event. Typically, a publisher raises an event when some action occurred. The subscribers, who are interested in getting a notification when an action occurred, should register with an event and handle it. In C#, an event is an encapsulated delegate. It is dependent on the delegate. The delegate defines the signature for the event handler method of the subscriber class.
Throw Keyword
An exception can be raised manually by using the throw keyword. Any type of exceptions which is derived from Exception class can be raised using the throw keyword. ex. if (std == null) throw new NullReferenceException("Student object is null.");
Indexers
An indexer is a special type of property that allows a class or a structure to be accessed like an array for its internal collection. C# allows us to define custom indexers, generic indexers, and also overload indexers. An indexer can be defined the same way as property with this keyword and square brackets []. Ex. public string this[int index] Indexer can also be generic. The following generic class includes generic indexer.
Interface
An interface includes the declarations of related functionalities. The entities that implement the interface must provide the implementation of declared functionalities. In C#, an interface can be defined using the interface keyword. An interface can contain declarations of methods, properties, indexers, and events. However, it cannot contain fields, auto-implemented properties. A class or a Struct can implement one or more interfaces using colon (:). An interface can be implemented explicitly using <InterfaceName>.<MemberName>. Explicit implementation is useful when class is implementing multiple interfaces; thereby, it is more readable and eliminates the confusion. It is also useful if interfaces have the same method name coincidently.
Nullable Types
As you know, a value type cannot be assigned a null value. For example, int i = null will give you a compile time error. C# 2.0 introduced nullable types that allow you to assign null to value type variables. You can declare nullable types using Nullable<t> where T is a type.
Object Initializer
C# 3.0 (.NET 3.5) introduced Object Initializer Syntax, a new way to initialize an object of a class or collection. Object initializers allow you to assign values to the fields or properties at the time of creating an object without invoking a constructor.
Dynamic Types
C# 4.0 (.NET 4.5) introduced a new type called dynamic that avoids compile-time type checking. A dynamic type escapes type checking at compile-time; instead, it resolves type at run time. A dynamic type variables are defined using the dynamic keyword. The compiler compiles dynamic types into object types in most cases. However, the actual type of a dynamic type variable would be resolved at run-time. If you assign a class object to the dynamic type, then the compiler would not check for correct methods and properties name of a dynamic type that holds the custom class object
Generic Constraint
C# allows you to use constraints to restrict client code to specify certain types while instantiating generic types. It will give a compile-time error if you try to instantiate a generic type using a type that is not allowed by the specified constraints. You can specify one or more constraints on the generic type using the where clause after the generic type name. ex. GenericTypeName<T> where T : contraint1, constraint2
Ternary Operator
C# includes a decision-making operator ?: which is called the conditional operator or ternary operator. It is the short form of the if else conditions. Ex. condition ? statement 1 : statement 2
Stream I/O
C# includes following standard IO (Input/Output) classes to read/write from different sources like files, memory, network, isolated storage, etc. Stream: System.IO.Stream is an abstract class that provides standard methods to transfer bytes (read, write, etc.) to the source. It is like a wrapper class to transfer bytes. Classes that need to read/write bytes from a particular source must implement the Stream class. The following classes inherit Stream class to provide the functionality to Read/Write bytes from a particular source: FileStream reads or writes bytes from/to a physical file, whether it is a .txt, .exe, .jpg, or any other file. FileStream is derived from the Stream class. MemoryStream: MemoryStream reads or writes bytes that are stored in memory. BufferedStream: BufferedStream reads or writes bytes from other Streams to improve certain I/O operations' performance. NetworkStream: NetworkStream reads or writes bytes from a network socket. PipeStream: PipeStream reads or writes bytes from different processes. CryptoStream: CryptoStream is for linking data streams to cryptographic transformations.
Collections
C# includes specialized classes that store series of values or objects are called collections. There are two types of collections available in C#: non-generic collections and generic collections. The System.Collections namespace contains the non-generic collection types and System.Collections.Generic namespace includes generic collection types. In most cases, it is recommended to use the generic collections because they perform faster than non-generic collections and also minimize exceptions by giving compile-time errors.
Custom Exception
C# includes the built-in exception types such as NullReferenceException, MemoryOverflowException, etc. However, you often like to raise an exception when the business rule of your application gets violated. So, for this, you can create a custom exception class by deriving the ApplicationException class. The .Net framework includes ApplicationException class since .Net v1.0. It was designed to use as a base class for the custom exception class. However, Microsoft now recommends Exception class to create a custom exception class.
Data Types
C# is a strongly-typed language. It means we must declare the type of a variable that indicates the kind of values it is going to store, such as integer, float, decimal, text, etc. Ex. string stringVar = "Hello World!!"; int intVar = 100; float floatVar = 10.2f; char charVar = 'A'; bool boolVar = true; C# mainly categorized data types in two types: Value types and Reference types. Value types include simple types (such as int, float, bool, and char), enum types, struct types, and Nullable value types. Reference types include class types, interface types, delegate types, and array types. Learn about value types and reference types in detail in the next chapter. Predefined data types include bool, int, float, etc.
Files and Directories
C# provides the following classes to work with the File system. They can be used to access directories, access files, open files for reading or writing, create a new file or move existing files from one location to another, etc. C# includes static File class to perform I/O operation on physical file system. The static File class includes various utility method to interact with physical file of any type e.g. binary, text etc. Use this static File class to perform some quick operation on physical file. It is not recommended to use File class for multiple operations on multiple files at the same time due to performance reasons. Use FileInfo class in that scenario.
Multidimensional Array
C# supports multidimensional arrays up to 32 dimensions. The multidimensional array can be declared by adding commas in the square brackets. For example, [,] declares two-dimensional array, [, ,] declares three-dimensional array, [, , ,] declares four-dimensional array, and so on. So, in a multidimensional array, no of commas = No of Dimensions - 1. the value of a two-dimensional array can be accessed by index no of row and column as [row index, column index]. So, [0, 0] returns the value of the first row and first column and [1, 1] returns the value from the second row and second column.
Contravariance
Contravariane is applied to parameters. Cotravariance allows a method with the parameter of a base class to be assigned to a delegate that expects the parameter of a derived class.
Covariance
Covariance enables you to pass a derived type where a base type is expected. Co-variance is like variance of the same kind. The base class and other derived classes are considered to be the same kind of class that adds extra functionalities to the base type. So covariance allows you to use a derived class where a base class is expected (rule: can accept big if small is expected).
Entity Framework
Entity Framework is an open-source ORM framework for .NET applications supported by Microsoft. It enables developers to work with data using objects of domain specific classes without focusing on the underlying database tables and columns where this data is stored. With the Entity Framework, developers can work at a higher level of abstraction when they deal with data, and can create and maintain data-oriented applications with less code compared with traditional applications. https://www.entityframeworktutorial.net/what-is-entityframework.aspx
Data Types - Default values
Every data type has a default value. Numeric type is 0, boolean has false, and char has '\0' as default value. Use the default(typename) to assign a default value of the data type Ex. int i = default(int);
Exception Handling
Exceptions in the application must be handled to prevent crashing of the program and unexpected result, log exceptions and continue with other functionalities. C# provides built-in support to handle the exception using try, catch & finally blocks.
Extension Method
Extension methods, as the name suggests, are additional methods. Extension methods allow you to inject additional methods without modifying, deriving or recompiling the original class, struct or interface. Extension methods can be added to your own custom class, .NET framework classes, or third party classes or interfaces.
Generics
Generic means the general form, not specific. In C#, generic means not specific to a particular data type. C# allows you to define generic classes, interfaces, abstract classes, fields, methods, static methods, properties, events, delegates, and operators using the type parameter and without the specific data type. A type parameter is a placeholder for a particular type specified when creating an instance of the generic type. A generic type is declared by specifying a type parameter in an angle brackets after a type name, e.g. TypeName<T> where T is a type parameter.
Variables
In C#, a variable contains a data value of the specific data type. Variable names must be unique. Variable names can contain letters, digits, and the underscore _ only. Variable names must start with a letter. Variable names are case-sensitive, num and Num are considered different names. Variable names cannot contain reserved keywords. Must prefix @ before keyword if want reserve keywords as identifiers. C# is the strongly typed language. It means you can assign a value of the specified data type. You cannot assign an integer value to string type or vice-versa.
Anonymous Type
In C#, an anonymous type is a type (class) without any name that can contain public read-only properties only. It cannot contain other members, such as fields, methods, events, etc. You create an anonymous type using the new operator with an object initializer syntax. The implicitly typed variable- var is used to hold the reference of anonymous types. Ex. var student = new { Id = 1, FirstName = "James", LastName = "Bond" }; The properties of anonymous types are read-only and cannot be initialized with a null, anonymous function, or a pointer type. The properties can be accessed using dot (.) notation, same as object properties. However, you cannot change the values of properties as they are read-only. An anonymous type will always be local to the method where it is defined. It cannot be returned from the method. However, an anonymous type can be passed to the method as object type parameter, but it is not recommended. If you need to pass it to another method, then use struct or class instead of an anonymous type.
Static Class, Methods, Constructors, Fields
In C#, static means something which cannot be instantiated. You cannot create an object of a static class and cannot access static members using an object. You can define one or more static methods in a non-static class. Static methods can be called without creating an object. You cannot call static methods using an object of the non-static class. The static methods can only call other static methods and access static members. You cannot access non-static members of the class in the static methods.
C# Struct
In C#, struct is the value type data type that represents data structures. It can contain a parameterized constructor, static constructor, constants, fields, methods, properties, indexers, operators, events, and nested types. struct can be used to hold small data values that do not require inheritance, e.g. coordinate points, key-value pairs, and complex data structure. A structure is declared using struct keyword. The default modifier is internal for the struct and its members. A struct cannot contain a parameterless constructor. It can only contain parameterized constructors or a static constructor. struct is a value type, so it is faster than a class object. Use struct whenever you want to just store the data. Generally, structs are good for game programming. However, it is easier to transfer a class object than a struct. So do not use struct when you are passing data across the wire or to other classes.
Collections - ArrayList
In C#, the ArrayList is a non-generic collection of objects whose size increases dynamically. It is the same as Array except that its size increases dynamically. An ArrayList can be used to add unknown data where you don't know the types and the size of the data.
Explicitly Typed Variable
In C#, variables must be declared with the data type. These are called explicitly typed variables. Ex. int i = 100;// explicitly typed variable
Partial Classes and Methods
In C#, you can split the implementation of a class, a struct, a method, or an interface in multiple .cs files using the partial keyword. The compiler will combine all the implementation from multiple .cs files when the program is compiled. Rules - All the partial class definitions must be in the same assembly and namespace. All the parts must have the same accessibility like public or private, etc. If any part is declared abstract, sealed or base type then the whole class is declared of the same type. Different parts can have different base types and so the final class will inherit all the base types. The Partial modifier can only appear immediately before the keywords class, struct, or interface. Nested partial types are allowed. Partial methods: Partial classes or structs can contain a method that split into two separate .cs files of the partial class or struct. One of the two .cs files must contain a signature of the method, and other file can contain an optional implementation of the partial method. Both declaration and implementation of a method must have the partial keyword.
Integers
Integer type numbers are positive or negative whole numbers without decimal points. C# includes four data types for integer numbers: byte, short, int, and long.
String Concatenation
Multiple strings can be concatenated with + operator. A String is immutable in C#. It means it is read-only and cannot be changed once created in the memory. Each time you concatenate strings, .NET CLR will create a new memory location for the concatenated string. So, it is recommended to use StringBuilder instead of string if you concatenate more than five strings.
Operators
Operators in C# are some special symbols that perform some action on operands. In mathematics, the plus symbol (+) do the sum of the left and right numbers. In the same way, C# includes various operators for different types of operations. The arithmetic operators perform arithmetic operations on all the numeric type operands such as sbyte, byte, short, ushort, int, uint, long, ulong, float, double, and decimal. The assignment operator = assigns its right had value to its left-hand variable, property, or indexer. It can also be used with other arithmetic, Boolean logical, and bitwise operators. Comparison operators compre two numeric operands and returns true or false. The equality operator checks whether the two operands are equal or not. The Boolean logical operators perform a logical operation on bool operands.(&&, ||, !)
Predicate Delegate
Predicate is the delegate like Func and Action delegates. It represents a method containing a set of criteria and checks whether the passed parameter meets those criteria. A predicate delegate methods must take one input parameter and return a boolean - true or false.
Collections - Queue
Queue is a special type of collection that stores the elements in FIFO style (First In First Out), exactly opposite of the Stack<T> collection. It contains the elements in the order they were added. C# includes generic Queue<T> and non-generic Queue collection. It is recommended to use the generic Queue<T> collection.
Collections - Stack
Stack is a special type of collection that stores elements in LIFO style (Last In First Out). C# includes the generic Stack<T> and non-generic Stack collection classes. It is recommended to use the generic Stack<T> collection. Stack is useful to store temporary data in LIFO style, and you might want to delete an element after retrieving its value.
String Interpolation
String interpolation is a better way of concatenating strings. We use + sign to concatenate string variables with static strings. C# 6 includes a special character $ to identify an interpolated string. An interpolated string is a mixture of static string and string variable where string variables should be in {} brackets. Ex. string fullName = $"Mr. {firstName} {lastName}, Code: {code}";
Collections - Dictionary
The Dictionary<TKey, TValue> is a generic collection that stores key-value pairs in no particular order. Keys cannot be duplicated.
FileInfo
The FileInfo class provides the same functionality as the static File class but you have more control on read/write operations on files by writing code manually for reading or writing bytes from a file.
Collections - Hashtable
The Hashtable is a non-generic collection that stores key-value pairs, similar to generic Dictionary<TKey, TValue> collection. It optimizes lookups by computing the hash code of each key and stores it in a different bucket internally and then matches the hash code of the specified key at the time of accessing values.
Collections - List
The List<T> is a collection of strongly typed objects that can be accessed by index and having methods for sorting, searching, and modifying list. It is the generic version of the ArrayList that comes under System.Collection.Generic namespace.
Collections - SortedList
The SortedList<TKey, TValue>, and SortedList are collection classes that can store key-value pairs that are sorted by the keys based on the associated IComparer implementation. For example, if the keys are of primitive types, then sorted in ascending order of keys. C# supports generic and non-generic SortedList. It is recommended to use generic SortedList<TKey, TValue> because it performs faster and less error-prone than the non-generic SortedList.
Tuple
The Tuple<T> class was introduced in .NET Framework 4.0. A tuple is a data structure that contains a sequence of elements of different data types. It can be used where you want to have a data structure to hold an object with properties, but you don't want to create a separate type for it. Ex. Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>
Byte
The byte data type stores numbers from 0 to 255. It occupies 8-bit in the memory. The byte keyword is an alias of the Byte struct in .NET. The sbyte is the same as byte, but it can store negative numbers from -128 to 127. The sbyte keyword is an alias for SByte struct in .NET.
Decimal
The decimal data type can store fractional numbers from ±1.0 x 10-28 to ±7.9228 x 1028. It occupies 16 bytes in the memory. The decimal is a keyword alias of the Decimal struct in .NET. The decimal type has more precision and a smaller range than both float and double, and so it is appropriate for financial and monetary calculations. Use m or M suffix with literal to make it decimal type.
Null
The default value of a reference type variable is null when they are not initialized. Null means not refering to any object.
Double
The double data type can store fractional numbers from 1.7eâˆ'308 to 1.7e+308. It occupies 8 bytes in the memory. The double keyword is an alias of the Double struct in .NET. Use d or D suffix with literal to make it double type.
C# Field
The field is a class-level variable that holds a value. Generally, field members should have a private access modifier and used with property.
Float
The float data type can store fractional numbers from 3.4eâˆ'038 to 3.4e+038. It occupies 4 bytes in the memory. The float keyword is an alias of Single struct in .NET. Use f or F suffix with literal to make it float type.
Int
The int data type is 32-bit signed integer. It can store numbers from -2,147,483,648 to 2,147,483,647. The int keyword is an alias of Int32 struct in .NET. The uint is 32-bit unsigned integer. The uint keyword is an alias of UInt32 struct in .NET. It can store positive numbers from 0 to 4,294,967,295. Optionally use U or u suffix after a number to assign it to uint variable.
Long
The long type is 64-bit signed integers. It can store numbers from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. Use l or L suffix with number to assign it to long type variable. The long keyword is an alias of Int64 struct in .NET. The ulong type stores positive numbers from 0 to 18,446,744,073,709,551,615. If a number is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, its type is ulong. The uint keyword is an alias of UInt64 struct in .NET.
Namespace
The namespace is a container for a set of related classes and namespaces. The namespace is also used to give unique names to classes within the namespace name. Namespace and classes are represented using a dot (.).
Short
The short data type is a signed integer that can store numbers from -32,768 to 32,767. It occupies 16-bit memory. The short keyword is an alias for Int16 struct in .NET. The ushort data type is an unsigned integer. It can store only positive numbers from 0 to 65,535. The ushort keyword is an alias for UInt16 struct in .NET.
Data Types - Conversions
The values of certain data types are automatically converted to different data types in C#. This is called an implicit conversion. Ex. int i = 345; float f = i; Console.WriteLine(f); //output: 345 In the above example, the value of an integer variable i is assigned to the variable of float type f because this conversion operation is predefined in C#. However, not all data types are implicitly converted to other data types. For example, int type cannot be converted to uint implicitly.
Delegates
What if we want to pass a function as a parameter? How does C# handles the callback functions or event handler? The answer is - delegate. The delegate is a reference type data type that defines the method signature. You can define variables of delegate, just like other data type, that can refer to any method with the same signature as the delegate. There are three steps involved while working with delegates: Declare a delegate Set a target method Invoke a delegate A delegate can be declared using the delegate keyword followed by a function signature. Ex. public delegate void MyDelegate(string msg);