2016-01-08 59 views
1

是的,我知道,ICollectionICollection<T>是兩回事。讓我來描述一下我想,雖然...分配我的ICollection <T>到ICollection的財產

這是我希望做什麼:

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定義:

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; } 
} 

UPDATE:最終結果 - 這是我現在使用的東西。

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; 
} 
+2

你的問題是,到底是什麼? –

+0

在我的評論中:report.ReportSections.Add(chapAffil); //在這一點上,我期望report.ReportSections.First()。ReportItems //擁有來自提交的記錄,但我有'null'。 –

+1

您需要重寫您的問題,以便明確*說明*具體說明*您需要什麼。不要讓人們挖掘你的代碼行,試圖破譯你想弄明白的東西。 –

回答

1

因爲您用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>; } 
    } 

} 
1

的問題是,你的ChapterAffiliates類隱藏從ReportSectionBase繼承了ReportItems財產。請參閱MSDN documentation on the new modifier。通過集合訪問實例時,引用的類型爲ReportSectionBase。因此,ReportItems屬性尚未設置。訪問ChapterAffiliates實例的ReportItems屬性的唯一方法是在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一個泛型類。 type參數將指定您的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 collection guidelines

+0

是的,這是有道理的。下一個問題是,爲什麼不能這樣工作:'public override ICollection ReportItems {get;組; }如果我在ChapterAffiliates類中使用它。 'var chapAffil = new ChapterAffiliates {ReportItems = Submissions};'因爲我試圖將ICollection 分配給ICollection,所以出現編譯錯誤。但是我不能在我的基類中定義ICollection ,所以我如何得到我想要的東西? –

+0

我想使ReportSectionBase泛型,但我不得不將ReportBase定義爲泛型。 '公共ICollection ReportSections {get;組; }'不會編譯。 –

+0

@MKenyonII是的,您將不得不使報告庫通用並指定報告部分和報告項目的類型。看到我的更新建議。 – lenkan