0

基本クラスから派生クラスのオーバーライドされたプロパティのセッターを呼び出すことができないようです。これはできるはずのことのように思えますが、私は明らかに何かが欠けています。以下のSearchSurveyBaseクラスのDisplayQuestionメソッドでは、この行は設定を行っていないようです。

VisibleQuestions.Add(sqc.SurveyQuestion.ID);

VisibleQuestionsは、派生クラスでオーバーライドされている抽象リストです。ゲッターはベースからはうまく機能しているようです。デバッグ時に派生クラスでヒットしているのがわかります。ただし、セッターはまったく機能していないようです。ゲッターはファインと呼ばれますが、セッターは決してセットしません。ここで何が欠けていますか?これを行うためのより良い方法はありますか?

基本クラス:

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?これが問題の短いバージョンです。

基本クラスと派生クラスがあります。基本クラスのメソッドで、派生クラスでオーバーライドされる抽象プロパティの値を設定できるようにしたいのですが、機能していません。

4

3 に答える 3

1

次のステートメントがVisibleQuestionsのセッターを呼び出すことを期待している場合は、間違っています。

VisibleQuestions.Add(sqc.SurveyQuestion.ID);

List<int>このステートメントは、VisibleQuestionsゲッターによって返されたインスタンスのAddメソッドを呼び出します。

次のように、VisibleQuestionsに値を割り当てた場合、セッターを利用できます。

VisibleQuestions = new List<int>();
于 2012-06-13T18:06:29.690 に答える
1

その行でセッターを呼び出していません。要素を追加するリストを返すゲッターを呼び出しています。ただし、次に同じゲッターにアクセスするときは、(要素を追加せずに)新しいリストを作成し、それを新たに返します。

于 2012-06-13T18:06:43.187 に答える
0

MSDNから-プロパティの使用(C#プログラミングガイド)-セットアクセサー

プロパティに値を割り当てると、新しい値を提供する引数を使用してsetアクセサーが呼び出されます。

セッターは、プロパティの値を実際に設定した場合にのみ呼び出されます。あなたの場合、基礎となるフィールドの値に基づいて新しいリストを返すゲッターを呼び出しています。リストを更新した後でその基になるフィールドを更新する場合は、次のように、プロパティの値を更新されたリストに設定する必要があります。

// 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;
于 2012-06-13T18:10:18.787 に答える