繁体   English   中英

C# - 当我尝试创建构造函数时,出现 CS7036 错误

[英]C# - When i try to create constructor, i get CS7036 error

首先,对不起我的英语。 我希望我能解释我的问题。

我有这样的课

public class CarCommandExecutorBase
{
    protected readonly ICarCommand CarCommand;
    public CarCommandExecutorBase(ICarCommand carCommand)
    {
        CarCommand = carCommand;
    }
}

我也有这样的课

public class CarStringCommandExecutor : CarCommandExecutorBase, IStringCommand
{
    private Car _Car;
    public CarStringCommandExecutor(Car car)
    {
        _Car = car;
        // this Constructor gives me an error.
    }
    public void ExecuteCommand(string commandObject)
    {
        if (string.IsNullOrEmpty(commandObject))
            throw new Exception("Komutlarda hata var.");

        char[] commands = commandObject.ToCharArray();

        for (int i = 0; i < commands.Length; i++)
        {
            switch (commands[i])
            {
                case 'L':
                    break;
                case 'R':
                    break;
                case 'M':
                    break;
                default:
                    throw new Exception("Komutlarda hata var.");
            }
        }
    }
}

错误信息: 错误

是什么原因,我该如何解决? 谢谢。

由于“编译器魔法”,关于 C# 类的一件事不是立即显而易见的,就是每个类都有一个构造函数

必须这样,因为对象构造发生在树中是一个规则; 您构造了一些继承自YZ ,该类继承自X继承自object ,并且Z的构造函数调用Y的调用X的调用object的,然后它们按object, X, Y, Z顺序完成并且你有你精心构建的东西 - 树上的每个构造函数都有机会进行初始化并准备好使用对象(每个构造函数负责的部分)

即使类似乎没有构造函数,也有构造函数

class X { 

}

如果您不提供构造函数,C# 会为您提供一个。 你永远不会在你的源代码中看到它; 想象一下,在读取文件和编译文件之间,编译器会为您插入它。 它没有参数,没有代码,除了调用它的基类之外什么都不做:

class X { 
  X():base() { } //C# invisibly writes this for you
}

如果您提供了一个构造函数但不编写base...位,C# 会在幕后为您放置base() (并且它总是调用无参数base() )但关键的是它不提供一个空的构造函数,如果你已经提供了一个

这意味着如果你有一个类:

class X{
  X(string message){
    ...
  }
}

你的类 X 有一个构造函数,所以 C# 不会提供空的,所以现在任何试图构造你的类的东西都必须提供一个string message

X x = new X("hello");

如果您现在从 X 继承,您可能会执行以下 3 件事之一(使用 Y):

class Y:X{

}
  1. 您没有添加构造函数,C# 会添加一个构造函数,但它只是愚蠢地调用base() ,这不起作用,因为 X 中没有不带参数的构造函数:

     class Y:X{ Y():base() { } }
  2. 您添加了一个构造函数,但保留了base位。 C# 再次添加它,就像base() ——出于同样的原因,这也不起作用

    class Y:X{ Y(int myArg) //c# adds base() in here for you { ... } }
  3. 您添加了一个包含对base调用的构造函数,并且因为您知道您的基类只有一个带有字符串 arg 的构造函数,所以您传递了一个:

     class Y:X{ Y(int myArg) : base("hello") { ... } }

所以你在场景 2 中,你要么需要:

  • 向基类添加一个无参数构造函数,以便 c# 的自动插入的东西起作用,或者,
  • 使用合适的参数添加对base(...)的调用,以阻止 C# 将base()放入

为了清楚地展示要点,我在此答案中的代码中省略了访问修饰符。 构造函数是否可访问也与所有这些有关,但我认为它超出了范围

由于CarCommandExecutorBase唯一的构造CarCommandExecutorBase是这样定义的

public CarCommandExecutorBase(ICarCommand carCommand)
{
    CarCommand = carCommand;
}

创建ICarCommand的实例时,您必须传递CarCommandExecutorBase

您必须通过ICarCommand的构造函数提供CarStringCommandExecutor ,因为在实例化派生类型时,也会调用基本构造函数。

有关更多详细信息,请参阅此答案: https : //stackoverflow.com/a/1882778/8450550

您可以执行以下操作来解决此错误:

public class CarStringCommandExecutor : CarCommandExecutorBase, IStringCommand
{
    ...

    public CarStringCommandExecutor(Car car, ICarCommand carCommand)
        : base(carCommand) // base() points to the constructor of the base class
    {
        ...
    }

或者这个

public class CarStringCommandExecutor : CarCommandExecutorBase, IStringCommand
{
    ...

    public CarStringCommandExecutor(Car car)
        : base(null) // passing null but be aware of NullReferenceExceptions
    {
        ...
    }

或者您向CarCommandExecutorBase添加另一个不需要参数的构造函数:

public class CarCommandExecutorBase
{
    protected readonly ICarCommand CarCommand;
    public CarCommandExecutorBase(ICarCommand carCommand)
    {
        CarCommand = carCommand;
    }

    // mark this constructor as protected, so only deriving types can call it
    protected CarCommandExecutorBase()
    {

    }
}

哪种解决方案最适合您的情况取决于您。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM