是的,我知道ICollection和ICollection<T>是两种不同的东西。让我描述一下我在尝试什么..。
这就是我想要做的:
public class SubmissionListViewModel
{
public ICollection<ProjectSubmissionViewModel> Submissions { get; set; }
public ReportBase GetContribAuthorsReport()
{
var report = new ContribAuthorsReport{ ReportType = "CSV" };
var chapAffil = new ChapterAffiliates {ReportItems = Submissions};
report.ReportSections.Add(chapAffil);
// AT this point, I would expect report.ReportSections.First().ReportItems
// to have the records from Submissions, but I have `null`.
return report;
}
}问题:为什么report.ReportSections.First().ReportItems为空?(请参见上文代码中的注释。)
下面是如何定义ContribAuthorsReport和ChapterAffiliates:
public class ContribAuthorsReport : ReportBase
{
public ContribAuthorsReport()
{
ReportSections = new List<ReportSectionBase>();
}
public override string ReportName { get { return "Contributing Affiliates' Contact Information"; } }
}
public class ChapterAffiliates : ReportSectionBase
{
public override string ReportSectionName { get { return "Chapter Affiliates"; } }
// This is what I have now
new public ICollection<ProjectSubmissionViewModel> ReportItems { get; set; }
// This won't compile
//public override ICollection<ProjectSubmissionViewModel> ReportItems { get; set; }
// This would compile, but breaks GetContribAuthorsReport()
//public override ICollection ReportItems { get; set; }
}我将拥有继承自ReportSectionBase的其他类,这些类将具有不同的ICollection模型。我认为这个问题源于如何定义基类。(见下文)
我的基类。
public abstract class ReportBase
{
virtual public string ReportType { get; set; }
virtual public string ReportName { get; set; }
public ICollection<ReportSectionBase> ReportSections { get; set; }
}
public abstract class ReportSectionBase
{
virtual public string ReportSectionName { get; set; }
virtual public ICollection ReportItems { get; set; }
} 更新:最终结果-以下是我现在使用的内容。
public class ReportBase
{
public ReportBase()
{
ReportSections = new List<IReportSection>();
}
public string ReportType { get; set; }
public string ReportName { get; set; }
public ICollection<IReportSection> ReportSections { get; set; }
}
public interface IReportSection
{
string ReportSectionName { get; }
ICollection ReportItems { get; set; }
}
public class ReportSection<T> : IReportSection
{
public string ReportSectionName { get; set; }
public ICollection<T> ReportItems { get; set; }
ICollection IReportSection.ReportItems
{
get { return ReportItems as ICollection; }
set { ReportItems = value as ICollection<T>; }
}
}这样我就可以很容易地定义一个报告:
public ReportBase GetContribAuthorsReport
(
ICollection<ProjectAffiliateViewModel> projectAffiliates,
ICollection<SubmissionAffiliateViewModel> submissionAffiliates
)
{
var caReport = new ReportBase { ReportType = "CSV", ReportName = "Reviewers' Contact Information" };
caReport.ReportSections.Add(new ReportSection<ProjectAffiliateViewModel> { ReportItems = projectAffiliates });
caReport.ReportSections.Add(new ReportSection<SubmissionAffiliateViewModel> { ReportItems = submissionAffiliates });
return caReport;
}发布于 2016-01-08 14:59:40
因为使用new隐藏集合,所以方法不是虚拟的,这意味着当您使用ReportSectionBase变量时,它将不会使用您的新集合。
解决这一问题的最简单方法是将抽象类更改为接口,这允许您对基类进行显式实现,但也可以公开泛型集合。
public abstract class ReportBase
{
virtual public string ReportType { get; set; }
virtual public string ReportName { get; set; }
public ICollection<IReportSection> ReportSections { get; set; }
}
public interface IReportSection
{
string ReportSectionName { get; }
ICollection ReportItems { get; set; }
}
public class ContribAuthorsReport : ReportBase
{
public ContribAuthorsReport()
{
ReportSections = new List<IReportSection>();
}
public override string ReportName { get { return "Contributing Affiliates' Contact Information"; } }
}
public class ChapterAffiliates : IReportSection
{
public string ReportSectionName { get { return "Chapter Affiliates"; } }
public ICollection<ProjectSubmissionViewModel> ReportItems { get; set; }
ICollection IReportSection.ReportItems {
get { return ReportItems as ICollection; }
set { ReportItems = value as ICollection<ProjectSubmissionViewModel>; }
}
}发布于 2016-01-08 14:57:45
问题是ChapterAffiliates类隐藏了从ReportSectionBase继承的ReportItems属性。见修饰符。当通过集合访问实例时,引用的类型为ReportSectionBase。因此,尚未设置ReportItems属性。访问ReportItems实例的ChapterAffiliates属性的唯一方法是对ChapterAffiliates类型的引用进行访问。
ChapterAffiliates a = new ChapterAffiliates { ReportItems = Submissions};
ReportSectionBase b = new ChapterAffiliates { ReportItems = Submissions};
// a.ReportItems == Submissions; returns true
// b.ReportItems == null; returns true
// ((ChapterAffiliates) b).ReportItems == Submissions; returns true 要解决这个问题,我将使您的ReportSectionBase成为一个泛型类。类型参数将指定ReportItems的类型。这样,您不需要将集合变为虚拟的,因为它将在基类中提供。而且,它保证了所有类型的安全。在我看来这是件好事。
public abstract class ReportBase<TReportSection, TReportItem> where TReportSection : ReportSectionBase<TReportItem>
{
public virtual string ReportType { get; set; }
public virtual string ReportName { get; set; }
public ICollection<TReportSection> ReportSections { get; set; }
}
public abstract class ReportSectionBase<TReportItem>
{
public virtual string ReportSectionName { get; set; }
public ICollection<TReportItem> ReportItems { get; set; }
}
public class ChapterAffiliates : ReportSectionBase<ProjectSubmissionViewModel>
{
public override string ReportSectionName { get { return "Chapter Affiliates"; } }
}
public class ContribAuthorsReport : ReportBase<ChapterAffiliates, ProjectSubmissionViewModel>
{
public ContribAuthorsReport()
{
ReportSections = new List<ChapterAffiliates>();
}
public override string ReportName { get { return "Contributing Affiliates' Contact Information"; } }
}此外,考虑不要公开可设置的集合属性。在MSDN收集指南中不建议这样做。
https://stackoverflow.com/questions/34679620
复制相似问题