C#设置从base的派生属性

时间:2012-06-13 17:57:50

标签: c# asp.net

我似乎无法从基类调用派生类中的重写属性的setter。这似乎是人们应该做的事情,但我显然遗漏了一些东西。在下面的SearchSurveyBase类的DisplayQuestion方法中,此行似乎没有进行任何设置:

VisibleQuestions.Add(sqc.SurveyQuestion.ID);

VisibleQuestions是一个在派生类中重写的抽象List。吸气者似乎从基地工作得很好;调试时我可以看到它们在派生类上被击中。但是,设置器似乎根本不起作用。 getter被称为罚款,但是setter从未设置过。我在这里错过了什么?有更好的方法吗?

基类:

public abstract class SearchSurveyBase : System.Web.UI.UserControl
{
    public abstract List<int> VisibleQuestions { get; set; }

    public abstract void SetupControls();

    protected void AddQuestion(Accordion accSection, Question question)
    {
        SearchQuestionControl searchQuestionControl = GetQuestionControl(question.ControlType);

        if (searchQuestionControl != null)
        {
            //QuestionVisible is a method that checks to see if the object's id is in the VisibleQuestions list
            searchQuestionControl.Visible = QuestionVisible(question);

            if (!searchQuestionControl.Visible)
            {
                string btnID = "lb_" + accSection.ID.ToString() + "_" + accSection.Panes.Count;
                LinkButton btn = new LinkButton();
                btn.ID = btnID;
                btn.Text = question.Text;
                btn.CommandArgument = questionPane.ID;
                btn.Command += new CommandEventHandler(DisplayQuestion);
                questionPane.HeaderContainer.Controls.Add(btn);
            }

            questionPane.ContentContainer.Controls.Add(searchQuestionControl);
            searchQuestionControlList.Add(searchQuestionControl);
        }
        accSection.Panes.Add(questionPane);
    }

    private void DisplayQuestion(object sender, CommandEventArgs e)
    {
        SearchQuestionControl sqc = null;
        AccordionPane pane = (AccordionPane)UIUtilities.FindControlRecursive(RootControl, e.CommandArgument.ToString());
        if (pane != null && pane.ContentContainer.HasControls() && pane.ContentContainer.Controls[0] is SearchQuestionControl)
        {
            sqc = (SearchQuestionControl)pane.ContentContainer.Controls[0];
        }

        if (sqc != null)
        {
            if (!sqc.Visible)
            {
                //Removed a bunch of lines that aren't relevant to the question per request.
                VisibleQuestions.Add(sqc.SurveyQuestion.ID);
            }
        }
    }
}

派生类:

public partial class SearchSurveyAccordion : SearchSurveyBase
{
    override public List<int> VisibleQuestions
    {
        get
        {
            // hfVisibleQuestions is a HiddenField control on the .ascx page that inherits this class.
            if (!string.IsNullOrWhiteSpace(hfVisibleQuestions.Value))
            {
                string[] vals = hfVisibleQuestions.Value.Split(',');
                List<int> vqs = new List<int>(Array.ConvertAll<string, int>(vals, (x => Convert.ToInt32(x))));
                return vqs;
            }
            else
            {
                return new List<int>();
            }
        }
        set
        {
            hfVisibleQuestions.Value = string.Join(",", value.Select(n => n.ToString()).ToArray());
        }
    }

    // This method is called during the Page_Init of the page that is consuming this user control.
    override public void SetupControls()
    {
        if (base.survey != null && base.survey.QuestionList != null && base.survey.QuestionList.Count > 0)
        {
            BuildAccordion(base.survey.QuestionList);
        }
    }

    private void BuildAccordion(List<Question> questionList)
    {
        Accordion accSection = null;
        foreach (Question question in questionList)
        {
            accSection = base.AddSection(accSurvey, defaultSectionHeader);
            AddQuestion(accSection, question);
        }
    }
}

TL; DR?这是问题的简短版本。

我有一个基类和一个派生类。我希望基类中的一个方法能够设置在派生类中重写的抽象属性的值,但它对我不起作用。

3 个答案:

答案 0 :(得分:1)

如果您希望以下语句为VisibleQuestions调用setter,那么您就错了:

VisibleQuestions.Add(sqc.SurveyQuestion.ID);

此语句调用VisibleQuestions getter返回的List<int>实例上的Add方法。

如果您为VisibleQuestions指定了值,则会使用setter,如下所示:

VisibleQuestions = new List<int>();

答案 1 :(得分:1)

您没有在该行上调用setter。您正在调用getter,它返回您添加元素的列表。但是,下次访问相同的getter时,您将创建一个新列表(没有添加的元素),您将重新返回

答案 2 :(得分:0)

来自MSDN - Using Properties (C# Programming Guide) - The set Accessor

  

为属性指定值时,将调用set访问器   通过使用提供新值的参数。

只有在实际设置属性值时才会调用setter。在您的情况下,您正在调用getter,它会根据基础字段的值返回一个新列表。如果您希望在更新列表后更新该基础字段,则需要将该属性的值设置为更新列表,如下所示:

// Calls the getter and returns a new list
List<string> questions = VisibleQuestions; 

// Updates the list, but does not trigger the setter
questions.Add(sqc.SurveyQuestion.ID); 

// Calls the setter
VisibleQuestions = questions;