C# - 当我尝试创建构造函数时,出现 CS7036 错误
C# - When i try to create constructor, i get CS7036 error
首先,对不起我的英语。我希望我能解释我的问题。
我有class这样的
public class CarCommandExecutorBase
{
protected readonly ICarCommand CarCommand;
public CarCommandExecutorBase(ICarCommand carCommand)
{
CarCommand = carCommand;
}
}
我也有class这样的
public class CarStringCommandExecutor : CarCommandExecutorBase, IStringCommand
{
public CarStringCommandExecutor(Car car)
{
// this Constructor gives me an error.
}
public void ExecuteCommand(string commandObject)
{
}
}
错误信息:
[![错误][1]][1]
这是什么原因,我该如何解决?谢谢
关于 C# class,由于“编译器的魔力”,其中一件事不是很明显,每个 class 都有一个构造函数
需要这样,因为对象构造发生在树中是规则;你构造了一些 class Z
继承自 Y
继承自 X
继承自 object
,Z
的构造函数调用 Y
的调用 X
的调用 object
的,然后它们按 object, X, Y, Z
的顺序完成,你就得到了你精心构造的东西——树上的每个构造函数有机会执行它的初始化并准备好对象以供使用(每个构造函数负责的部分)
甚至 classes 似乎没有构造函数,但有构造函数:
class X {
}
如果您不提供构造函数,C# 会为您提供一个。您永远不会在源代码中看到它;想象一下,在读取文件和编译文件之间,编译器会为您插入它。它没有参数,没有代码,除了调用它的基之外什么也不做:
class X {
X():base() { } //C# invisibly writes this for you
}
如果您提供构造函数但不写入 base...
位,C# 会在幕后为您放入 base()
(它总是调用无参数 base()
) 但重要的是 如果您已经提供一个构造函数,它不会提供一个空的构造函数
这意味着如果您 class 喜欢:
class X{
X(string message){
...
}
}
你的 class X 有一个构造函数,所以 C# 不会提供空的,所以现在任何试图构造你的 class 的东西都必须提供一个 string message
:
X x = new X("hello");
如果您现在从 X 继承,您可能会做以下 3 件事之一(使用 Y):
class Y:X{
}
您不添加构造函数,C# 添加一个,但它只是愚蠢地调用 base()
,这不起作用,因为 X 中没有不带参数的构造函数:
class Y:X{
Y():base() { }
}
您添加了一个构造函数,但省略了 base
位。 C# 添加了它,同样只是字面上的 base()
- 由于同样的原因,这也不起作用
class Y:X{
Y(int myArg) //c# adds base() in here for you
{
...
}
}
你添加了一个包含对 base
的调用的构造函数,因为你知道你的基础 class 只有一个带有字符串 arg 的构造函数,所以你传递了一个:
class Y:X{
Y(int myArg) : base("hello")
{
...
}
}
所以你在场景 2 中,你需要:
- 向基础 class 添加一个无参数构造函数,以便 c# 的自动插入的东西起作用,或者,
- 使用合适的参数添加对
base(...)
的调用,以阻止 C# 将 base()
放入
为了清楚地展示要点,我在这个答案的代码中省略了访问修饰符。构造函数是否可访问也可能与所有这些有关,但我认为它超出了范围
由于CarCommandExecutorBase
中唯一的构造函数是这样定义的
public CarCommandExecutorBase(ICarCommand carCommand)
{
CarCommand = carCommand;
}
在创建 CarCommandExecutorBase
.
的实例时,您 必须 传递 ICarCommand
您必须通过 CarStringCommandExecutor
的构造函数提供 ICarCommand
,因为在实例化派生类型时,基构造函数也会被调用。
有关此问题的更多详细信息,请参阅此答案:
你可以这样做来解决这个错误:
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()
{
}
}
哪种解决方案最适合您的情况取决于您。
首先,对不起我的英语。我希望我能解释我的问题。
我有class这样的
public class CarCommandExecutorBase
{
protected readonly ICarCommand CarCommand;
public CarCommandExecutorBase(ICarCommand carCommand)
{
CarCommand = carCommand;
}
}
我也有class这样的
public class CarStringCommandExecutor : CarCommandExecutorBase, IStringCommand
{
public CarStringCommandExecutor(Car car)
{
// this Constructor gives me an error.
}
public void ExecuteCommand(string commandObject)
{
}
}
错误信息: [![错误][1]][1]
这是什么原因,我该如何解决?谢谢
关于 C# class,由于“编译器的魔力”,其中一件事不是很明显,每个 class 都有一个构造函数
需要这样,因为对象构造发生在树中是规则;你构造了一些 class Z
继承自 Y
继承自 X
继承自 object
,Z
的构造函数调用 Y
的调用 X
的调用 object
的,然后它们按 object, X, Y, Z
的顺序完成,你就得到了你精心构造的东西——树上的每个构造函数有机会执行它的初始化并准备好对象以供使用(每个构造函数负责的部分)
甚至 classes 似乎没有构造函数,但有构造函数:
class X {
}
如果您不提供构造函数,C# 会为您提供一个。您永远不会在源代码中看到它;想象一下,在读取文件和编译文件之间,编译器会为您插入它。它没有参数,没有代码,除了调用它的基之外什么也不做:
class X {
X():base() { } //C# invisibly writes this for you
}
如果您提供构造函数但不写入 base...
位,C# 会在幕后为您放入 base()
(它总是调用无参数 base()
) 但重要的是 如果您已经提供一个构造函数,它不会提供一个空的构造函数
这意味着如果您 class 喜欢:
class X{
X(string message){
...
}
}
你的 class X 有一个构造函数,所以 C# 不会提供空的,所以现在任何试图构造你的 class 的东西都必须提供一个 string message
:
X x = new X("hello");
如果您现在从 X 继承,您可能会做以下 3 件事之一(使用 Y):
class Y:X{
}
您不添加构造函数,C# 添加一个,但它只是愚蠢地调用
base()
,这不起作用,因为 X 中没有不带参数的构造函数:class Y:X{ Y():base() { } }
您添加了一个构造函数,但省略了
base
位。 C# 添加了它,同样只是字面上的base()
- 由于同样的原因,这也不起作用class Y:X{ Y(int myArg) //c# adds base() in here for you { ... } }
你添加了一个包含对
base
的调用的构造函数,因为你知道你的基础 class 只有一个带有字符串 arg 的构造函数,所以你传递了一个:class Y:X{ Y(int myArg) : base("hello") { ... } }
所以你在场景 2 中,你需要:
- 向基础 class 添加一个无参数构造函数,以便 c# 的自动插入的东西起作用,或者,
- 使用合适的参数添加对
base(...)
的调用,以阻止 C# 将base()
放入
为了清楚地展示要点,我在这个答案的代码中省略了访问修饰符。构造函数是否可访问也可能与所有这些有关,但我认为它超出了范围
由于CarCommandExecutorBase
中唯一的构造函数是这样定义的
public CarCommandExecutorBase(ICarCommand carCommand)
{
CarCommand = carCommand;
}
在创建 CarCommandExecutorBase
.
ICarCommand
您必须通过 CarStringCommandExecutor
的构造函数提供 ICarCommand
,因为在实例化派生类型时,基构造函数也会被调用。
有关此问题的更多详细信息,请参阅此答案:
你可以这样做来解决这个错误:
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()
{
}
}
哪种解决方案最适合您的情况取决于您。