首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将我的ICollection<T>分配给ICollection属性

将我的ICollection<T>分配给ICollection属性
EN

Stack Overflow用户
提问于 2016-01-08 14:41:40
回答 2查看 947关注 0票数 1

是的,我知道ICollectionICollection<T>是两种不同的东西。让我描述一下我在尝试什么..。

这就是我想要做的:

代码语言:javascript
复制
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为空?(请参见上文代码中的注释。)

下面是如何定义ContribAuthorsReportChapterAffiliates

代码语言:javascript
复制
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模型。我认为这个问题源于如何定义基类。(见下文)

我的基类。

代码语言:javascript
复制
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; }
} 

更新:最终结果-以下是我现在使用的内容。

代码语言:javascript
复制
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>; }
    }
}

这样我就可以很容易地定义一个报告:

代码语言:javascript
复制
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;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-08 14:59:40

因为使用new隐藏集合,所以方法不是虚拟的,这意味着当您使用ReportSectionBase变量时,它将不会使用您的新集合。

解决这一问题的最简单方法是将抽象类更改为接口,这允许您对基类进行显式实现,但也可以公开泛型集合。

代码语言:javascript
复制
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>; }
    }

}
票数 1
EN

Stack Overflow用户

发布于 2016-01-08 14:57:45

问题是ChapterAffiliates类隐藏了从ReportSectionBase继承的ReportItems属性。见修饰符。当通过集合访问实例时,引用的类型为ReportSectionBase。因此,尚未设置ReportItems属性。访问ReportItems实例的ChapterAffiliates属性的唯一方法是对ChapterAffiliates类型的引用进行访问。

代码语言:javascript
复制
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的类型。这样,您不需要将集合变为虚拟的,因为它将在基类中提供。而且,它保证了所有类型的安全。在我看来这是件好事。

代码语言:javascript
复制
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收集指南中不建议这样做。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34679620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档