是否可以将参数从派生类的默认构造函数传递给基构造函数
本文关键字:构造函数 默认 参数 派生 是否 | 更新日期: 2023-09-27 18:30:57
假设我有一个抽象的基类Deck:
public abstract class Deck
{
public List<Card> cards;
public Deck(string[] values, string[] suits)
{...}
...
}
和一个派生类 EuchreDeck:
public class EuchreDeck : Deck
{
string[] values = new string[] { "9", "10", "J", "Q", "K", "A" };
string[] suits = new string[] { "clubs", "spades", "hearts", "diamonds" };
public EuchreDeck() : base(values, suits) // Error.
{}
...
}
我希望能够实例化EuchreDeck
并将两个字符串数组传递给基类,即 var gameDeck = new EuchreDeck();
.
目前我收到错误:"非静态字段、方法或属性EuchreDeck.values
需要对象引用。
这是否可能,或者调用派生的默认构造函数将始终调用基默认构造函数?
是的,如果你把数组static
,你可以这样做:
public class EuchreDeck : Deck
{
private static readonly string[] values = new string[] { "9", "10", "J", "Q", "K", "A" };
private static readonly string[] suits = new string[] { "clubs", "spades", "hearts", "diamonds" };
public EuchreDeck() : base(values, suits)
{
}
}
不能像使用实例级成员那样使用它的原因是这样做是不合法的。这来自 C# 规范 10.10.1 构造函数初始值设定项,其中指出:
实例构造函数初始值设定项无法访问正在 创建。因此,在 构造函数初始值设定项的参数表达式,因为它是一个 参数表达式引用任何参数的编译时错误 通过简单名称的实例成员。
通过将数组切换为static
,它们不再通过实例访问,而是通过EuchreDeck
类型访问。
也就是说,我可能会建议您对设计进行轻微调整。也许使用工厂为您创建这些专用甲板,而不是它们的构造函数。
举个例子,也许重构这样的东西:
将基本Deck
更改为仅取一组卡片:
public abstract class Deck
{
public List<Card> Cards;
protected Deck(IEnumerable<Card> cards)
{
this.Cards = new List<Card>(cards);
}
}
然后像这样进行出厂设置:
public class EuchreDeck : Deck
{
private EuchreDeck(IEnumerable<Card> cards) : base(cards)
{
}
public class Factory : DeckFactory
{
private static readonly string[] Values = new string[] { "9", "10", "J", "Q", "K", "A" };
private static readonly string[] Suits = new string[] { "clubs", "spades", "hearts", "diamonds" };
public static EuchreDeck Create()
{
var cards = CreateCards(Values, Suits);
return new EuchreDeck(cards);
}
}
}
实例化/用法为:
EuchreDeck.Factory.Create();
您可以尝试工厂用法。我只是将其嵌套在类中,因此您无法使用无效的卡片集创建EuchreDeck
。您的DeckFactory
基将具有您的转换方法(看起来您当前在Deck
构造函数中具有)
除此之外,我不确定您是否对EuchreDeck
有特殊需求;我假设您还有其他与之相关的方法?如果没有,你可能会完全放弃这个类,让工厂创建一个带有所需卡片的Deck
。
我认为问题在于值和花色应该声明为静态的。
static string[] values = new string[] { "9", "10", "J", "Q", "K", "A" };
static string[] suits = new string[] { "clubs", "spades", "hearts", "diamonds" };
这样,它们将在实例化新类时可用。
你必须在某个地方贴花变量:
public EuchreDeck() : base(values, suits) // Error.
{}
在哪里申报values
和suits
?
您必须static
定义它们,例如:
static readonly string[] values = new string[] { "9", "10", "J", "Q", "K", "A" };
static readonly string[] suits = new string[]
{ "clubs", "spades", "hearts", "diamonds" };
问题是base(..)
只能访问 ctor 范围内可见的值。因此,您不能传递实例变量,因为实例在该级别上无法访问,但您可以传递调用类的 ctor 参数和静态成员。