为什么我得到这个编译错误试图调用基构造函数/方法,需要一个动态的说法? [英] Why do I get this compile error trying to call a base constructor/method that takes a dynamic argument?

查看:253
本文介绍了为什么我得到这个编译错误试图调用基构造函数/方法,需要一个动态的说法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然重构了一些code,我碰到这种奇怪的编译错误:

While refactoring some code, I came across this strange compile error:

构造函数调用需要进行动态调度,但也不能因为它是一个构造函数初始化的一部分。考虑强制转换动态参数。

The constructor call needs to be dynamically dispatched, but cannot be because it is part of a constructor initializer. Consider casting the dynamic arguments.

这似乎试图调用基方法/带动态参数的构造函数时发生的。例如:

It seems to occur when trying to call base methods/constructors that take dynamic arguments. For example:

class ClassA
{
    public ClassA(dynamic test)
    {
        Console.WriteLine("ClassA");
    }
}

class ClassB : ClassA
{
    public ClassB(dynamic test)
        : base(test)
    {
        Console.WriteLine("ClassB");
    }
}

它的工作原理,如果我投的参数对象,像这样的:

public ClassB(dynamic test)
    : base((object)test)

所以,我有点糊涂了。为什么我必须把这个讨厌的中投 - 为什么不能在编译器弄清楚我的意思

So, I'm a little confused. Why do I have to put this nasty cast in - why can't the compiler figure out what I mean?

推荐答案

构造函数链必须在编译时被确定为肯定的 - 编译器必须挑选过载,以便它可以创建有效的IL。而通常重载解析(如方法调用)可以被推迟到执行时间,即不进行链式构造函数调用工作。

The constructor chain has to be determined for certain at compile-time - the compiler has to pick an overload so that it can create valid IL. Whereas normally overload resolution (e.g. for method calls) can be deferred until execution time, that doesn't work for chained constructor calls.

编辑:在正常C#code(前C#4,基本)的所有的重载是在编译时进行的。然而,当一个成员调用涉及一个动态值,也就是在执行时解决。例如,考虑这样的:

In "normal" C# code (before C# 4, basically), all overload resolution is performed at compile-time. However, when a member invocation involves a dynamic value, that is resolved at execution time. For example consider this:

using System;

class Program
{
    static void Foo(int x)
    {
        Console.WriteLine("int!");
    }

    static void Foo(string x)
    {
        Console.WriteLine("string!");
    }

    static void Main(string[] args)  
    {
        dynamic d = 10;
        Foo(d);
    }
}

编译器不会发出直接调用在这里 - 它不能,因为在调用美孚(D)不知道超载会解析。相反,它会发出code这确实一种及时小汇编解决与过载的实际的类型 D 的执行时间。

The compiler doesn't emit a direct call to Foo here - it can't, because in the call Foo(d) it doesn't know which overload it would resolve to. Instead it emits code which does a sort of "just in time" mini-compilation to resolve the overload with the actual type of the value of d at execution time.

现在,不用于构造函数链的工作,为有效IL必须包含一个呼叫到一个特定的基类构造函数。 (我不知道是不是动态的版本甚至不能的 EX pressed 的IL中,还是可以的,但结果将是无法证实的。)

Now that doesn't work for constructor chaining, as valid IL has to contain a call to a specific base class constructor. (I don't know whether the dynamic version can't even be expressed in IL, or whether it can, but the result would be unverifiable.)

您可能会说,C#编译器应该能够告诉大家,有实际上只一个可见的构造函数的可以的调用,并且它们的构造的总是的是可利用的。 。但一旦你开始在这条道路,你最终是一种语言的非常的复杂规定。 C#的设计者通常需要有更简单的规则,有时并不强大,你希望他们成为的位置。

You could argue that the C# compiler should be able to tell that there's only actually one visible constructor which can be called, and that constructor will always be available... but once you start down that road, you end up with a language which is very complicated to specify. The C# designers usually take the position of having simpler rules which occasionally aren't as powerful as you'd like them to be.

这篇关于为什么我得到这个编译错误试图调用基构造函数/方法,需要一个动态的说法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆