Both ref and out are used when we want to pass paremeters to a method and allow that method to read and modify data.
ref tells the compiler that the object is initialized before entering the function, while
out tells the compiler that the object will be initialized inside the function.
ref is two-ways,
out is out-only.
WHERE clause introduces a condition on individual rows;
HAVING clause introduces a condition on aggregations, i.e. results of selection where a single result, such as count, average, min, max, or sum, has been produced from multiple rows.
As a rule of thumb, use
GROUP BY and
GROUP BY. It is a rather primitive rule, but it is useful in more than 90% of the cases.
SELECT L.LectID, Fname, Lname
FROM Lecturers L
JOIN Lecturers_Specialization S ON L.LectID=S.LectID
GROUP BY L.LectID, Fname, Lname
(SELECT COUNT(Expertise) FROM Lecturers_Specialization GROUP BY LectID)
- Can support inheritance
- Are reference (pointer) types
- The reference can be null
- Have memory overhead per new instance
- Cannot support inheritance
- Are value types
- Cannot have a null reference (unless Nullable is used)
- Do not have a memory overhead per new instance – unless ‘boxed’
- Cannot have explicit parameterless constructor
- Cannot have destructor
Both Classes and Structs:
- Are compound data types typically used to contain a few variables that have some logical relationship
- Can contain methods and events
- Can support interfaces
CONSIDER a struct instead of a class:
- If instances of the type are small and commonly short-lived or are commonly embedded in other objects.
AVOID a struct unless the type has all of the following characteristics:
- It logically represents a single value, similar to primitive types (int, double, etc.).
- It has an instance size under 16 bytes.
- It is immutable. (cannot be changed)
- It will not have to be boxed frequently.
lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock. The following example includes a
private Object thisLock = new Object();
public void Withdraw(decimal amount)
if (amount > balance)
throw new Exception("Insufficient funds");
balance -= amount;
lock keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released.
You can’t use the await keyword in the body of a
Reflection provides objects (of type Type) that describe assemblies, modules and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you are using attributes in your code, reflection enables you to access them. For more information, see Attributes.
Here’s a simple example of reflection using the static method
GetType – inherited by all types from the
Object base class – to obtain the type of a variable:
// Using GetType to obtain type information:
int i = 42;
System.Type type = i.GetType();
The following example uses reflection to obtain the full name of the loaded assembly.
// Using Reflection to get information from an Assembly:
System.Reflection.Assembly info = typeof(System.Int32).Assembly;
mscorlib, Version=126.96.36.199, Culture=neutral, PublicKeyToken=b77a5c561934e089
Reflection is useful in the following situations:
When you have to access attributes in your program’s metadata. For more information, see Retrieving Information Stored in Attributes.
For examining and instantiating types in an assembly.
For building new types at runtime. Use classes in System.Reflection.Emit.
For performing late binding, accessing methods on types created at run time. See the topic Dynamically Loading and Using Types.
A lambda expression is an anonymous function that you can use to create delegates or expression tree types. By using lambda expressions, you can write local functions that can be passed as arguments or returned as the value of function calls. Lambda expressions are particularly helpful for writing LINQ query expressions.
To create a lambda expression, you specify input parameters (if any) on the left side of the lambda operator =>, and you put the expression or statement block on the other side. For example, the lambda expression
x => x * x specifies a parameter that’s named
x and returns the value of
x squared. You can assign this expression to a delegate type, as the following example shows:
delegate int del(int i);
static void Main(string args)
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
To create an expression tree type:
static void Main(string args)
Expression<del> myET = x => x * x;
Read more: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions
In computing, a hash table (hash map) is a data structure that can map keys to values. A hash table uses a hash function to compute an index into an array of buckets or slots, from which the desired value can be found.