C# dynamic is a trap door: stop the leaks before they…
    Neura MarketNeura Market/DeepSeek
    ChatGPTChatGPTClaudeClaudeGeminiGeminiCursorCursorGrokGrokPerplexityPerplexityDeepSeekDeepSeek
    CoPilotCoPilotStable DiffusionStable DiffusionMidjourneyMidjourney
    View All Directories
    OverviewRulesPromptsMCPsAgentsGamesBlogVideosGuidesCoursesCommunityTrending
    DeepSeekBlogC# dynamic is a trap door: stop the leaks before they spread (Must read for Dapper users)
    Back to Blog
    C# dynamic is a trap door: stop the leaks before they spread (Must read for Dapper users)
    csharp

    C# dynamic is a trap door: stop the leaks before they spread (Must read for Dapper users)

    Dmitry Dorogoy January 14, 2026
    0 views

    In C#, dynamic can be handy at boundaries. The problem is that it can silently leak into places where...

    In C#, dynamic can be handy at boundaries. The problem is that it can silently leak into places where you expect static typing, and your method signatures can still look perfectly safe.

    I ran into these leaks in real projects, so I built a small Roslyn analyzer to catch them early. I am the author of DynamicLeakAnalyzer (NuGet: DimonSmart.DynamicLeakAnalyzer), and this post explains the problem it targets and how to fix leaks at the boundary.

    What dynamic really means

    In C#, dynamic is a static type, but it bypasses compile-time type checking for the expression. Member access, overload resolution, operators, and conversions are bound at runtime.

    At runtime, values still flow as object. The difference is that the compiler emits runtime binding (DLR call sites). Those call sites have caching, so repeated calls can get faster after the first bind.

    How "dynamic contagion" happens

    Two patterns make leaks hard to spot during review:

    • Invisible runtime work: member access and conversions happen at runtime.
    • Deceptive signatures: a method can return int and still perform dynamic conversions inside.
    • var can silently become dynamic: when the right side is dynamic, the inferred type becomes dynamic.

    Here is a small example that shows both problems. The method looks fully static and returns int, yet dynamic enters through the parameter.

    class Program
    {
        static int GetX(int i) => i;
    
        static void Main()
        {
            dynamic prm = 123;
    
            int a = GetX(prm); // DSM001: implicit dynamic conversion at runtime
            var b = GetX(prm); // DSM002: b becomes dynamic because the invocation is dynamic
        }
    }
    

    In real code, prm is often not a local variable. It can be an object passed into the method, and dynamic can hide in a field or property, for example prm.Payload.Id.

    The Dapper trap

    Dapper makes it easy to introduce dynamic without noticing it. Calling QueryFirst without <T> returns a dynamic row object (usually DapperRow), so property access becomes dynamic.

    using Dapper;
    using System.Data;
    
    public static class Repo
    {
        public static int GetActiveUserId(IDbConnection cn)
        {
            // QueryFirst() without <T> returns a dynamic row (DapperRow).
            var row = cn.QueryFirst("select Id from Users where IsActive = 1");
    
            // row.Id is dynamic, the conversion to int happens at runtime.
            return row.Id; // DSM001
        }
    }
    

    This kind of code often passes reviews because the signature says int. The dynamic binding is hidden in the middle.

    Safer alternatives in Dapper

    Prefer typed APIs at the boundary:

    int id = cn.QuerySingle<int>("select Id from Users where IsActive = 1");
    

    Or map to a small DTO:

    public sealed record UserId(int Id);
    
    int id = cn.QuerySingle<UserId>("select Id from Users where IsActive = 1").Id;
    

    If you really must use a dynamic row, kill it immediately:

    var row = cn.QueryFirst("select Id from Users where IsActive = 1");
    int id = (int)row.Id;
    

    The goal is not "never use dynamic". The goal is "stop the leak at the boundary".

    The solution: DynamicLeakAnalyzer

    DynamicLeakAnalyzer is a Roslyn analyzer that makes these leaks loud before they spread.

    It reports two rules:

    • DSM001 (Implicit dynamic conversion): a dynamic expression is used where a static type is expected (return, assignment, argument, etc.). The code compiles, but the conversion happens at runtime.
    • DSM002 (var inferred as dynamic): var captures a dynamic result and becomes dynamic.

    Install and enforce

    Add the analyzer:

    dotnet add package DimonSmart.DynamicLeakAnalyzer
    

    Make warnings hurt using .editorconfig:

    root = true
    
    [*.cs]
    dotnet_diagnostic.DSM001.severity = error
    dotnet_diagnostic.DSM002.severity = error
    

    Where dynamic is fine, and where it is not

    Good boundary examples:

    • COM interop
    • JSON adapters and glue code
    • database adapters (including dynamic Dapper rows)

    Avoid dynamic in:

    • core domain logic
    • hot loops
    • libraries meant for other developers

    Next steps

    • Run the analyzer on a real codebase and see where dynamic leaks already exist.
    • If you use Dapper, search for QueryFirst( and non-generic Query( calls that return dynamic rows.
    • If you have false positives or missed cases, open an issue with a minimal repro.

    Tags

    csharproslyndapperdotnet

    Comments

    More Blog

    View all
    Five Gemma-4 models, one accelerator: what porting E2B 31B to AWS Inferentia2 taught megemma

    Five Gemma-4 models, one accelerator: what porting E2B 31B to AWS Inferentia2 taught me

    I ported the whole Gemma-4 family — E2B, E4B, 12B, 31B, and the 26B-A4B MoE — to run on...

    X
    xbill
    Hey DEV, I'm Tobore. Let's actually connect.community

    Hey DEV, I'm Tobore. Let's actually connect.

    Hey DEV, I'm Tobore. Let's actually connect. I've been on here for a while now, mostly writing and...

    L
    Laurina Ayarah
    I burned through thousands of AI tokens. Then a friend did it for freeai

    I burned through thousands of AI tokens. Then a friend did it for free

    (yep, kinda clickbait, just for the funsies 😊) At the beginning of the year, I relaunched my...

    P
    Paulo Henrique
    Claude might be saturating your machineai

    Claude might be saturating your machine

    My laptop was sitting idle with the fan at full tilt. Nothing was running that I knew of. The culprit...

    S
    Sidhant Panda
    Automated GitHub Code Reviews Using Google Geminigithubactions

    Automated GitHub Code Reviews Using Google Gemini

    I Built a Thing! TL;DR — Google Gemini-based Pull Request reviews and Issue Triaging for...

    D
    Darren "Dazbo" Lester
    What is an "agentic harness," actually?ai

    What is an "agentic harness," actually?

    I've been hearing the word "harness" thrown around a lot lately. I assumed it just meant "the IDE" or...

    T
    Tilde A. Thurium

    Stay up to date

    Get the latest DeepSeek prompts, rules, and resources delivered to your inbox weekly.

    Neura Market LogoNeura Market

    Discover the best AI prompts, plugins, and resources for DeepSeek and more.

    Content Types

    • Rules
    • Prompts
    • MCPs
    • Agents
    • Guides

    Platforms

    • ChatGPT Directory
    • Claude Directory
    • Gemini Directory
    • Cursor Directory
    • Grok Directory
    • Perplexity Directory
    • DeepSeek Directory
    • CoPilot Directory
    • Stable Diffusion Directory
    • Midjourney Directory
    • All Directories

    Resources

    • Blog
    • Documentation
    • Help Center
    • Marketplace

    Legal

    • Privacy Policy
    • Terms of Service

    © 2026 Neura Market. All rights reserved.

    |

    Not affiliated with any AI platform vendors.

    Neura Market

    Custom AI Systems & Services

    Our team of experienced AI builders will help build custom AI systems, workflows, and solutions for your business.

    Request custom work

    Ready-made automations for this

    Workflows from the Neura Market marketplace related to this DeepSeek resource

    • Automate Blog Content Creation with Notion MCP, DeepSeek AI, and WordPressn8n · $9.99 · Related topic
    • Dynamic Media Library with On-Demand Downloads for Radarr/Sonarr and Plexn8n · $24.99 · Related topic
    • Cheaper, Faster, Accurate Answers with Memory Summarization & Dynamic Routing!n8n · $24.99 · Related topic
    • Generate AI Videos from Scripts with DeepSeek, Synthesia, and Together.ain8n · $24.99 · Related topic
    Browse all workflows