我可以将参数从派生类的默认构造函数传递给基构造函数吗? [英] Can I pass arguments to a base constructor from a derived class's default constructor?

查看:27
本文介绍了我可以将参数从派生类的默认构造函数传递给基构造函数吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Suppose I have an abstract base class Deck:

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

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

   ...
}

和一个派生类 EuchreDeck:

and a derived class 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();.

I want the ability to instantiate EuchreDeck and have the two string arrays passed to the base class, i.e. var gameDeck = new EuchreDeck();.

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

Currently I'm getting the error: "An object reference is required for the non-static field, method, or property EuchreDeck.values."

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

Is this possible, or will calling the derived default constructor always call the base default constructor?

推荐答案

是的,如果您将数组设为 static 就可以做到这一点:

Yes, you can do this if you make the arrays 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 Constructor Initializers 它指出:

The reason why you can't use it as you had with instance-level members is because it's not legal to do so. This comes from the C# specification 10.10.1 Constructor Initializers where it states:

一个实例构造函数初始化器不能访问被创建.因此,在编译时引用它是一个错误构造函数初始值设定项的参数表达式,因为它是一个引用任何参数表达式的编译时错误通过简单名称的实例成员.

An instance constructor initializer cannot access the instance being created. Therefore it is a compile-time error to reference this in an argument expression of the constructor initializer, as is it a compile-time error for an argument expression to reference any instance member through a simple-name.

通过将数组切换为 static,它们不再通过实例访问,而是通过 EuchreDeck type 访问.

By switching the arrays to be static, they are no longer accessed via the instance but rather by the EuchreDeck type.

也就是说,我可能会建议您对设计稍作调整.也许使用工厂为您而不是他们的构造者创建这些专门的甲板.

That said, I might suggest you take a slight tweak on the design. Maybe use a factory to create these specialized decks for you rather than their constructors.

作为一个示例,可以重构如下:

As an example, maybe refactor something like this:

改变你的基础Deck,只拿这组牌:

Change your base Deck to just take the set of cards:

public abstract class Deck
{
    public List<Card> Cards;
    protected Deck(IEnumerable<Card> cards)
    {
        this.Cards = new List<Card>(cards);
    }
}

然后像这样进行出厂设置:

Then have the factory setup like this:

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 构造函数中有)

You could play around with the factory usage. I just nested it in the class so you couldn't create a EuchreDeck with an invalid set of cards. Your DeckFactory base would have your conversion method (which looks like you currently have in your Deck constructor)

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

Beyond that, I'm not sure if you have a specific need for a EuchreDeck; I'm assuming you have other methods associated with it? If not, you could probably ditch the class altogether and just let the factory create a Deck with the needed cards.

这篇关于我可以将参数从派生类的默认构造函数传递给基构造函数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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