【问题标题】:Is there any way of setting a value to a subclass property and it appears in a different base class property?有没有办法为子类属性设置一个值并且它出现在不同的基类属性中?
【发布时间】:2020-12-04 06:49:48
【问题描述】:

是否有任何方法可以将值 X 设置为子类属性 (TextAnswers[]) 并出现在基类属性 (Answers[]) 上? 我对另外两个类也有类似的问题,但是由于我想要的属性在基类和子类中都是相同的类型,所以很容易。我只是让属性放在基类上。

在这种情况下,属性是不同类型的(IAnswerOption 和 AnswerOptionImage)。

在我看来,完美的解决方案是在子类上设置一个属性并尝试将值传递给基类,但我对此感到很困惑。我在下面留下了代码,如果您不明白我的意图,我可以更好地解释它。

这是我的基类:

[System.Serializable]
public class Question : IQuestion<IAnswerOption>
{
    public virtual IAnswerOption[] Answers { get; set; }
}

这是我的子类:

[System.Serializable]
public class AudioQuestion : Question
{
    [field: SerializeField] private AnswerOptionImage[] answerOptions;

    public IAnswerOption[] AnswerOptions
    {
        get { return (IAnswerOption[]) answerOptions;}
        set { answerOptions = (AnswerOptionImage[]) Answers;  }
    }

    public string audioName;
}

问题出现在这里。我有一堂课收到了一个问题。我创建了一个 Question 类型的属性,以便能够接收 Question 的任何子类。我进行了调试,当我到达 foreach 时出现问题。

protected Question CurrentQuestion { get; set; }

public void Method() 
{
    foreach (var answer in CurrentQuestion.Answers)
    {
           
    }
}

如您所见,AnswerOptions 已填满:

但是 CurrentQuestion.Answers 为空

如果有人可以帮助我,我将不胜感激。谢谢。

【问题讨论】:

  • 问题不清楚,你想做什么?你有一个类接收“泛型类”的参数以允许传递它的子类,然后我没有关注你
  • 我将 Question 类作为基类。除此之外,我还有几个 Question 的子类,例如 AudioQuestion。两个课程都有答案。但是,问题可以有多种类型,答案也可以。正如您在上面看到的,我的问题在最后两张图片中得到了体现。作为 AudioQuestion 一部分的 AnswerOptions 已填充,但来自基类的 Answers 为空。我想要的是 CurrentQuestion.Answers 具有与 AnswerOptions 相同的值。

标签: c# oop unity3d properties


【解决方案1】:

这里的问题是Question.Answers 有一个公共的setter;这使得无法在子类中安全地使用更具体的类型。

例如:

public class SomeOtherAnswerOption : IAnswerOption { }

Question audioQuestion = new AudioQuestion();
audioQuestion.Answers = new SomeOtherAnswerOption[] { }; // You probably don't want to allow this

如果您从基类中删除公共设置器,您可以执行以下操作:

[System.Serializable]
public class Question : IQuestion<IAnswerOption>
{
    public virtual IAnswerOption[] Answers { get; protected set; } // Setter protected
}

[System.Serializable]
public class AudioQuestion : Question
{
    // Hide the base property but use it in the implementation
    public new AnswerOptionImage[] Answers
    {
        get => base.Answers as AnswerOptionImage[];
        set { base.Answers = value; }
    }
}

new 关键字隐藏了基类属性,但无论对象被视为Question 还是AudioQuestion,都可以检索到数组:

AudioQuestion audioQuestion = new AudioQuestion();
audioQuestion.Answers = new AnswerOptionImage[] { };

Question question = audioQuestion;
audioQuestion.Answers == question.Answers; // true;

question.Answers = new SomeOtherAnswerOption[] { }; // Compilation error

【讨论】:

    【解决方案2】:

    我通过这样做解决了这个问题:

        AudioQuestion audioQuestion = (AudioQuestion)unansweredQuestions[randomQuestionIndex];
        CurrentQuestion = audioQuestion;
        CurrentQuestion.Answers = audioQuestion.AnswerOptions;
    

    首先我将问题存储在 audioQuestion 中,然后将 audioquestion 分配给 CurrentQuestion,最后,我将 AnswerOptions[] 复制到 Answers[]。

    这样,当我检查 CurrentQuestion Answers[] 属性的值与 AnswerOptions[] 相同。

    【讨论】:

    • 这种方案违反了开闭原则。每次创建Question 的新子类时,您还需要记住更新此代码。如果你在其他地方做类似的事情,你就会遇到严重的维护问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    • 2022-01-15
    • 2023-03-23
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    相关资源
    最近更新 更多