C# and .NET Programming Glossary

Last updated:

Terms are grouped by topic. The “In C#” column says what the term means for this language specifically, which is often narrower than the general definition.

Type System

Term Definition In C#
Statically typed Variable types are fixed at compile time C# is statically typed. int count = 5 makes count = "hello" a compile error
Dynamically typed Types are determined at runtime Not C#’s default, though the dynamic keyword opts individual expressions into runtime binding
Strongly typed Type rules are enforced, with no implicit coercion between unrelated types C# is strongly typed. int n = "5" and if (count) on an int are compile errors. Two notable exceptions: + with a string operand converts the other side, so "5" + 3 is "53", and char converts to int implicitly, so 'a' + 1 is 98
Weakly typed Implicit coercion between unrelated types is allowed JavaScript’s "5" * 2 === 10, and if (0) coercing a number to a boolean. C# rejects both
Type inference The compiler deduces a type from context instead of requiring a declaration var items = new List<string>(). This is still static typing, because the type is fixed at compile time even though you didn’t write it
Nominal typing Compatibility comes from declared relationships C# is nominal. A class must declare that it implements an interface; matching method signatures is not enough
Structural typing Compatibility comes from shape TypeScript’s model. C# uses it only for language patterns, such as foreach accepting any type with a suitable GetEnumerator method, await any type with GetAwaiter, and deconstruction any type with Deconstruct
Covariance Preserves the type hierarchy, so IEnumerable<Dog> is usable as IEnumerable<Animal> Declared with out on a type parameter of a generic interface or delegate, and only for reference-type arguments. Safe because the parameter appears only in output positions
Contravariance Reverses the hierarchy, so Action<Animal> is usable as Action<Dog> Declared with in, with the same interface, delegate, and reference-type limits. Safe because the parameter appears only in input positions
Invariance No substitution in either direction List<Dog> is not a List<Animal>, because you could add a Cat through the Animal reference. Arrays are the exception: Dog[] converts to Animal[], and storing a Cat throws ArrayTypeMismatchException at run time

Statements and Expressions

Term Definition In C#
Expression Is evaluated, usually to a value 2 + 3, customer.Name, a method call (a void call is an expression with no value)
Statement Performs an action without producing a value if, for, a variable declaration. Statements run in sequence. An expression contains one only through the block body of a lambda or anonymous method
Statement-oriented language Control-flow constructs do not produce values To capture a result from branching, you declare a variable first and assign inside each path
Expression-oriented language Most constructs produce values F#, Rust, and Kotlin. In Rust, let x = if condition { a } else { b }; needs no temporary

C# began statement-oriented and has added expression-oriented constructs in most releases: the ternary operator (C# 1.0), LINQ query expressions (3.0), expression-bodied members (6.0), pattern matching (7.0 onward), and switch expressions (8.0). Assignment is both. x = 5 assigns and evaluates to 5, which is why a = b = c = 0 chains.

Data Characteristics

Term Definition In C#
Mutable Can be changed after creation List<T>. Adding an item changes the existing instance
Immutable Cannot be changed; “modification” produces a new instance string. A readonly struct allows no field changes after construction, and the positional properties of a record class or readonly record struct are init-only, though a plain record struct gets read-write ones. All of these are shallow, so a List<T> member can still have items added
Value type Stores data directly; assignment copies the data int, double, bool, enum, any struct. It lives wherever its container lives, which is not necessarily the stack
Reference type Stores a reference; assignment copies the reference, not the data class, record (but not record struct, which is a value type), interface, delegate, arrays, and string (immutable, but still a reference type)
Nullable Can hold a value or the absence of one int? is a distinct runtime type, Nullable<int>. With nullable reference types enabled, string? differs from string only in compiler analysis, and at run time both are string
Boxing Wrapping a value type in a heap-allocated object Happens on conversion to object, ValueType, Enum (from an enum), or any interface the type implements. Passing a value to a non-generic collection is the common case, and calling an inherited object method such as GetType() boxes too
Unboxing Extracting the value type back out Requires a cast to the boxed type or its nullable form. The runtime also lets an enum and its underlying type unbox as each other. Anything else throws InvalidCastException (a boxed int does not unbox to long), and unboxing a null reference to a non-nullable type throws NullReferenceException

Function Properties

Determinism, side effects, and idempotence are independent of each other. A function can be deterministic but impure, or idempotent but non-deterministic.

Term Definition Example
Pure Same output for the same input, and no side effects Math.Sqrt(4)
Impure Violates either property Anything that reads a database, writes a log, or mutates a parameter
Side effect Any observable change outside the return value Writing a file, sending a request, mutating global or input state
Idempotent Same end state whether run once or many times x = 5. HTTP PUT and DELETE. Incrementing is not
Deterministic Same return value for the same input Math.Max(3, 5). DateTime.Now and Random.Next() are not

DateTime.Now is non-deterministic but idempotent, since calling it changes no state. An INSERT that generates a new ID is neither.

Execution Models

Term Definition In C#
Blocking Halts the thread until the operation completes stream.Read(...), or .Result/.Wait() on a Task
Non-blocking Returns immediately and signals completion separately stream.ReadAsync(...) typically returns a task without waiting for the I/O, and the task completes when the read does
Synchronous Each operation finishes before the next begins The caller’s thread waits
Asynchronous An operation starts without blocking the calling thread await on an incomplete task pauses the logical flow but releases the thread while the operation is in flight. That release is the whole point, and it is why a server with a small thread pool can serve thousands of concurrent requests
Concurrent Multiple tasks in progress, interleaved A single core can run concurrent work by switching between tasks. Concurrency is about structure
Parallel Multiple tasks executing simultaneously Requires multiple cores. Parallelism is about execution
Thread-safe Correct when accessed from multiple threads at once Immutable data is inherently thread-safe; mutable shared state needs synchronization
Race condition Behavior depends on the relative timing of events Two threads read a counter as 5, both increment to 6, one increment is lost
Deadlock Two or more operations wait on each other indefinitely A holds lock 1 and wants lock 2; B holds lock 2 and wants lock 1. The common .NET form is .Result on a task under a single-threaded SynchronizationContext, where the blocked thread is the one the continuation needs

System Integration

Term Definition In C#
Interoperability Different systems, languages, or components working together P/Invoke (LibraryImport, DllImport) for native code, COM interop, and the shared runtime for other .NET languages
Impedance mismatch Friction when translating between paradigms or representations The object-relational case is canonical: inheritance and behavior on one side, tables and joins on the other
Marshalling Translating data between representations so systems with different memory layouts or calling conventions can exchange it A C# string is UTF-16 and a C char* is usually 8-bit and null-terminated. Blittable data (int, double, structs of them) crosses as-is, often pinned rather than copied. A string passed by value as UTF-16 is pinned too, but one marshalled as UTF-8 or ANSI is copied and converted, as are bool and non-blittable structs. MarshalAs overrides the conversion when the default is wrong
Serialization Flattening an in-memory object graph into a linear sequence of bytes or characters Data must become linear to cross a process or network boundary, since you cannot send a pointer over HTTP
Deserialization Rebuilding the graph from that linear form Format choice trades readability (JSON, XML) against size and speed (Protocol Buffers, MessagePack)

Memory and Resource Management

Term Definition In C#
Garbage collection The runtime reclaims memory that is no longer reachable Eliminates manual free and dangling pointers, at the cost of pauses and less predictable timing
Managed code Code whose execution a runtime controls The runtime allocates and frees memory, enforces type safety with cast and bounds checks, handles exceptions, and compiles IL to native code, at run time unless the app was compiled ahead of time
Unmanaged code Code opaque to the runtime C and C++ compiled to native instructions. The runtime can call into it but cannot manage its memory or reason about its types, and a crash inside it takes down the process
Disposable resource Holds something the GC cannot see or reason about A SqlConnection holds a pooled connection; a FileStream holds an OS file handle. IDisposable and using give deterministic release, since finalizers are a safety net rather than prompt cleanup
Memory leak Memory allocated and never freed In a GC language it usually means unintended references: event handlers never unsubscribed, static collections that only grow, caches with no eviction. Native memory from Marshal.AllocHGlobal or an undisposed handle can still leak the classic way

Abstraction and Design

Term Definition
Encapsulation Bundling data with the operations on it and restricting direct access to internals, so implementation can change without breaking callers
Abstraction Exposing essential features while hiding implementation. Good ones let you think at a higher level; poor ones leak details or hide what you needed
Polymorphism Treating different types uniformly through a common interface, with each supplying its own implementation
Coupling How dependent modules are on each other. Tight coupling makes changes ripple
Cohesion How related the elements inside a module are. Low cohesion makes a module hard to name and harder to maintain
Dependency injection Supplying a component’s dependencies rather than letting it construct them, so it depends on abstractions instead of concrete implementations

Error Handling

Term Definition
Exception An object describing a failure that propagates up the call stack until something handles it. One unhandled on a thread terminates the process. Some paths drop it instead: a faulted Task that nothing observes, and an exception thrown in a System.Timers.Timer handler
Throwing Signalling that something went wrong, for conditions the immediate code cannot handle
Catching Handling the condition, at a level where recovery is actually meaningful rather than merely to suppress it
Fail-fast Stopping at the first sign of an error rather than continuing in a possibly corrupted state. A null check that throws at method entry is fail-fast; substituting a default is not. In .NET the name also refers to Environment.FailFast, which terminates the process immediately without running finally blocks
Defensive programming Explicitly validating inputs, checking preconditions, and handling edge cases, balanced against checks so numerous they obscure the logic

Composition and Reuse

Term Definition In C#
Inheritance Creating a type by extending another and acquiring its behavior Single inheritance for classes. It couples child to parent and exposes the child to the fragile base class problem
Composition Creating functionality by combining objects More flexible, since composed objects can be swapped at runtime. Hence “favor composition over inheritance,” with inheritance reserved for genuine is-a relationships
Delegation Forwarding work to another object rather than implementing it How a decorator implements an interface by passing calls through to an inner instance. Unrelated to C#’s delegate keyword, which declares a type for method references
Higher-order function Takes functions as arguments or returns them Where and Select take a lambda describing the filter or projection
Closure A function that captures variables from its enclosing scope A lambda referencing a local can read and modify it after the enclosing method returns. That enables the pattern and can also extend object lifetimes unintentionally

Found this useful? Share it:

Share on LinkedIn