我似乎无法从基类调用派生类中的重写属性的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?这是问题的简短版本。
我有一个基类和一个派生类。我希望基类中的一个方法能够设置在派生类中重写的抽象属性的值,但它对我不起作用。
答案 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;