我可以从派生类的默认构造函数中将参数传递给基础构造函数吗?

Zac*_*ton 7 c# constructor abstract-class derived-class

假设我有一个抽象基类Deck:

public abstract class Deck
{
   public List<Card> cards;

   public Deck(string[] values, string[] suits)
   {...}

   ...
}
Run Code Online (Sandbox Code Playgroud)

和派生类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.
   {}

   ...
}
Run Code Online (Sandbox Code Playgroud)

我希望能够实例化EuchreDeck并将两个字符串数组传递给基类,即var gameDeck = new EuchreDeck();.

目前我收到错误:"非静态字段,方法或属性需要对象引用EuchreDeck.values."

这是可能的,还是调用派生的默认构造函数总是调用基本的默认构造函数?

Chr*_*air 11

是的,如果你制作数组,你可以这样做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)
   {

   }
}
Run Code Online (Sandbox Code Playgroud)

您不能像使用实例级成员那样使用它的原因是因为这样做是不合法的.这来自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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后让工厂设置如下:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

实例化/用法为:

EuchreDeck.Factory.Create();
Run Code Online (Sandbox Code Playgroud)

你可以玩工厂用法.我只是在课堂上嵌套它,所以你不能EuchreDeck用一组无效的卡创建一个.你的DeckFactory基础会有你的转换方法(看起来你现在在Deck构造函数中有)

除此之外,我不确定你是否有特定需要EuchreDeck; 我假设你有其他相关方法吗?如果没有,你可能完全放弃了这个课程,只需让工厂Deck用所需的卡片创建一个.