Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7540361
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T07:37:27+00:00 2026-05-30T07:37:27+00:00

Inspired by this question . Short version: Why can’t the compiler figure out the

  • 0

Inspired by this question.

Short version: Why can’t the compiler figure out the compile-time type of M(dynamic arg) if there is only one overload of M or all of the overloads of M have the same return type?

Per the spec, §7.6.5:

An invocation-expression is dynamically bound (§7.2.2) if at least one of the following holds:

  • The primary-expression has compile-time type dynamic.

  • At least one argument of the optional argument-list has compile-time type dynamic and the primary-expression does not have a delegate type.

It makes sense that for

class Foo {
    public int M(string s) { return 0; }
    public string M(int s) { return String.Empty; }
}

the compiler can’t figure out the compile-time type of

dynamic d = // dynamic
var x = new Foo().M(d);

because it won’t know until runtime which overload of M is invoked.

However, why can’t the compiler figure out the compile-time type if M has only one overload or all of the overloads of M return the same type?

I’m looking to understand why the spec doesn’t allow the compiler to type these expressions statically at compile time.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T07:37:28+00:00Added an answer on May 30, 2026 at 7:37 am

    UPDATE: This question was the subject of my blog on the 22nd of October, 2012. Thanks for the great question!


    Why can’t the compiler figure out the compile-type type of M(dynamic_expression) if there is only one overload of M or all of the overloads of M have the same return type?

    The compiler can figure out the compile-time type; the compile-time type is dynamic, and the compiler figures that out successfully.

    I think the question you intended to ask is:

    Why is the compile-time type of M(dynamic_expression) always dynamic, even in the rare and unlikely case that you’re making a completely unnecessary dynamic call to a method M that will always be chosen regardless of the argument type?

    When you phrase the question like that, it kinda answers itself. 🙂

    Reason one:

    The cases you envision are rare; in order for the compiler to be able to make the kind of inference you describe, enough information must be known so that the compiler can do almost a full static type analysis of the expression. But if you are in that scenario then why are you using dynamic in the first place? You would do far better to simply say:

    object d = whatever;
    Foo foo = new Foo();
    int x = (d is string) ? foo.M((string)d) : foo((int)d);
    

    Obviously if there is only one overload of M then it is even easier: cast the object to the desired type. If it fails at runtime because the cast it bad, well, dynamic would have failed too!

    There’s simply no need for dynamic in the first place in these sorts of scenarios, so why would we do a lot of expensive and difficult type inference work in the compiler to enable a scenario we don’t want you using dynamic for in the first place?

    Reason two:

    Suppose we did say that overload resolution has very special rules if the method group is statically known to contain one method. Great. Now we’ve just added a new kind of fragility to the language. Now adding a new overload changes the return type of a call to a completely different type — a type which not only causes dynamic semantics, but also boxes value types. But wait, it gets worse!

    // Foo corporation:
    class B
    {
    }
    
    // Bar corporation:
    class D : B
    {
        public int M(int x) { return x; }
    }
    
    // Baz corporation:
    dynamic dyn = whatever;
    D d = new D();
    var q = d.M(dyn);
    

    Let’s suppose that we implement your feature requiest and infer that q is int, by your logic. Now Foo corporation adds:

    class B
    {
        public string M(string x) { return x; }
    }
    

    And suddenly when Baz corporation recompiles their code, suddenly the type of q quietly turns to dynamic, because we don’t know at compile time that dyn is not a string. That is a bizarre and unexpected change in the static analysis! Why should a third party adding a new method to a base class cause the type of a local variable to change in an entirely different method in an entirely different class that is written at a different company, a company that does not even use B directly, but only via D?

    This is a new form of the Brittle Base Class problem, and we seek to minimize Brittle Base Class problems in C#.

    Or, what if instead Foo corp said:

    class B
    {
        protected string M(string x) { return x; }
    }
    

    Now, by your logic,

    var q = d.M(dyn);
    

    gives q the type int when the code above is outside of a type that inherits from D, but

    var q = this.M(dyn);
    

    gives the type of q as dynamic when inside a type that inherits from D! As a developer I would find that quite surprising.

    Reason Three:

    There is too much cleverness in C# already. Our aim is not to build a logic engine that can work out all possible type restrictions on all possible values given a particular program. We prefer to have general, understandable, comprehensible rules that can be written down easily and implemented without bugs. The spec is already eight hundred pages long and writing a bug-free compiler is incredibly difficult. Let’s not make it more difficult. Not to mention the expense of testing all those crazy cases.

    Reason four:

    Moreover: the language affords you many opportunities to avail yourself of the static type analyzer. If you are using dynamic, you are specifically asking for that analyzer to defer its action until runtime. It should not be a surprise that using the “stop doing static type analysis at compile time” feature causes static type analysis to not work very well at compile time.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Inspired by this question: How to manage Configuration Settings for each Developer How can
Inspired by this question How can I quickly identify most recently modified stored procedures
Inspired by this question : Is explicit type recursion possible in F#? type 'a
This question was inspired by this answer to another question, indicating that you can
Inspired by this question , I was trying to find out what exactly happens
Inspired by this question How can I force GDB to disassemble? I wondered about
Inspired by this question How can I force GDB to disassemble? and related to
Inspired by this question which started out innocently but is turning into a major
inspired by this question since i do not find any good sql casts out
Inspired by this question , I wanted to try my hand at the latest

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.