编译器为什么返回 `dynamic`,而不应该返回特定类型?

huangapple go评论74阅读模式
英文:

Why does compiler return `dynamic` when it should return a specific type?

问题

以下是我正在运行的确切代码。为什么编译器返回 dynamic 而不是类型 MyClass

我的项目正在运行在.NET Framework 4.7.2上,但我通过添加 public static class IsExternalInit { } 和以下配置来配置它以使用最新的C#:

<PropertyGroup>
    <LangVersion>latest</LangVersion>
</PropertyGroup>

我的代码:

internal class Program
{
    class MyClass
    {
    }

    static class MyParser
    {
        public static MyClass Parse(dynamic data)
        {
            return new MyClass();
        }
    }

    static void Do(dynamic data)
    {
        var parsedObj = MyParser.Parse(data);
        ...
    }

    static void Main(string[] args)
    {
        Do(JsonConvert.DeserializeObject(""));
    }
}

编译器为什么返回 `dynamic`,而不应该返回特定类型?

英文:

Below is the exact code I am running. Why does the compiler return dynamic and not type MyClass?

My project is running on .NET Framework 4.7.2, but I configured it to use latest C# by adding public static class IsExternalInit { } and

&lt;PropertyGroup&gt;
    &lt;LangVersion&gt;latest&lt;/LangVersion&gt;
&lt;/PropertyGroup&gt;

My code:

internal class Program
{
    class MyClass
    {
    }

    static class MyParser
    {
        public static MyClass Parse(dynamic data)
        {
            return new MyClass();
        }
    }

    static void Do(dynamic data)
    {
        var parsedObj = MyParser.Parse(data);
        ...
    }

    static void Main(string[] args)
    {
        Do(JsonConvert.DeserializeObject(&quot;&quot;));
    }
}

编译器为什么返回 `dynamic`,而不应该返回特定类型?

答案1

得分: 8

为什么编译器返回dynamic而不返回特定类型?

这个问题基于一个错误的前提。编译器的行为是正确的,所以问为什么它应该执行错误的操作,这让回答你的问题变得困难。

相反,我将回答一个问题:“规范的哪个部分决定了编译器何时应将调用分类为动态调用?”

我参考规范的第11.7.8.1节,其中规定:

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#11781-general

如果满足以下至少一项条件,调用表达式是动态绑定的(§11.3.3):

  • 主表达式具有编译时类型为dynamic。
  • 可选的argument_list中至少有一个参数具有编译时类型为dynamic。

在这种情况下,编译器将调用表达式分类为dynamic类型的值。

data是具有类型dynamic的“至少一个参数”,所以就是这样。

在你的特定情况下,还适用于附加错误检查的部分,但这部分不影响调用类型的分类。

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#1165-compile-time-checking-of-dynamic-member-invocation

如果你的“为什么”问题没有通过参考规范来回答,那么我鼓励你将其重新表述为一个“什么”问题。很难知道何时满意地回答“为什么”问题。

英文:

> Why does compiler return dynamic when it should return a specific type?

The question presupposes a falsehood. The compiler's behaviour is correct, so asking why it should do an incorrect thing makes it hard to answer your question.

Instead I'll answer the question "what section of the specification determines when the compiler should classify an invocation as dynamic?"


I refer you to section 11.7.8.1 of the specification, which states:

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#11781-general

> An invocation_expression is dynamically bound (§11.3.3) 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.
>
> In this case, the compiler classifies the invocation_expression as a
> value of type dynamic.

data is "at least one argument" that has type dynamic, so there you go.

In your specific case, the section on additional error checks applies -- but this section does not affect the classification of the invocation's type.

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#1165-compile-time-checking-of-dynamic-member-invocation


If your "why" question was not answered by a reference to the specification, then I'd encourage you to reformulate it as a "what" question. It's hard to know when a "why" question has been answered satisfactorily.

huangapple
  • 本文由 发表于 2023年1月9日 07:05:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75051916.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定