Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The dynamic keyword in C# is a static type that instructs the compiler to bypass compile-time type checking. Operations on variables declared as dynamic are deferred until runtime, where the Dynamic Language Runtime (DLR) takes over to resolve types, properties, and method invocations.
dynamic dynamicVariable = 10;
dynamicVariable = "Now I am a string"; // Valid: Type is evaluated at runtime
dynamicVariable.NonExistentMethod();   // Compiles successfully; throws RuntimeBinderException at runtime

Core Mechanics

When the C# compiler encounters the dynamic keyword, it does not emit standard Intermediate Language (IL) instructions for method calls or property access. Instead, it relies on the following mechanisms:
  1. Underlying Type: At the IL level, dynamic is compiled as System.Object. The compiler applies the System.Runtime.CompilerServices.DynamicAttribute to the metadata to signal to the runtime that the member requires dynamic dispatch.
  2. Dynamic Language Runtime (DLR): The compiler emits DLR “call site” payloads. A call site is a caching mechanism that records the runtime type of the object and the operation being performed.
  3. Late Binding: The DLR inspects the object’s actual System.Type at runtime. If the requested member exists and the arguments match, the DLR executes the operation. If the binding fails, it throws a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException.

dynamic vs. object vs. var

Understanding dynamic requires distinguishing it from object and var, as they dictate different phases of type resolution.
// var: Compile-time type inference. The compiler determines the exact type.
var implicitlyTyped = "String value";
// implicitlyTyped.Foo(); // COMPILER ERROR: string does not contain 'Foo'

// object: Compile-time type checking. The variable is strictly treated as System.Object.
object objectTyped = "String value";
// objectTyped.ToUpper(); // COMPILER ERROR: object does not contain 'ToUpper'

// dynamic: Runtime type resolution. The compiler ignores member validation.
dynamic dynamicallyTyped = "String value";
dynamicallyTyped.ToUpper(); // COMPILES. Executes successfully at runtime.

Implicit Conversions

The dynamic type supports implicit conversions to and from any other type. The compiler automatically inserts the necessary conversion logic, which is then evaluated by the DLR at runtime.
dynamic d = 42;      // Implicit conversion from int to dynamic
int i = d;           // Implicit conversion from dynamic to int
string s = d;        // Compiles, but throws RuntimeBinderException at runtime (cannot implicitly convert int to string)

Technical Limitations

Because dynamic strips away compile-time context, it introduces specific structural limitations:
  • Extension Methods: The DLR cannot resolve extension methods at runtime. Extension methods are a compile-time syntactic sugar that requires the compiler to search static classes in the current using directives.
dynamic list = new List<int> { 1, 2, 3 };
// list.FirstOrDefault(); // RuntimeBinderException
Enumerable.FirstOrDefault(list); // Valid: Explicit static method call
  • Anonymous Functions: You cannot assign a lambda expression directly to a dynamic variable because lambdas do not have a strict type until they are cast to a specific delegate or expression tree.
// dynamic d = x => x + 1; // COMPILER ERROR
dynamic d = (Func<int, int>)(x => x + 1); // Valid
  • Local Variable Type Inference: If a method returns dynamic, assigning its result to a variable declared with var results in the local variable also being typed as dynamic.
Master C# with Deep Grasping Methodology!Learn More