Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在服务层使用私有setter构建业务集合_C# - Fatal编程技术网

C# 在服务层使用私有setter构建业务集合

C# 在服务层使用私有setter构建业务集合,c#,C#,通常我认为这段代码是一个很好的设计: 查看集合的专用setter。因此,没有人可以从schoolclass对象之外分配新集合 public class Schoolclass { public Schoolclass() { Pupils = new List<Pupil>(); } public int SchoolclassId { get; set; }

通常我认为这段代码是一个很好的设计:

查看集合的专用setter。因此,没有人可以从schoolclass对象之外分配新集合

public class Schoolclass
    {
        public Schoolclass()
        {
            Pupils = new List<Pupil>();
        }            

        public int SchoolclassId { get; set; }
        public string SchoolclassCode { get; set; }

        public List<Pupil> Pupils { get; private set; }
    }
公共课堂
{
公立学校班级()
{
学生=新名单();
}            
public int SchoolclassId{get;set;}
公共字符串类代码{get;set;}
公共列表{get;private set;}
}
关于此样式,我的数据获取方法不再有效:

服务层调用SQLite数据提供程序:

基本法:

public IEnumerable GetAdministrationData()
{
var schoolclasses=adminDataProvider.GetSchoolclassList();
foreach(学校班级中的学校班级)
{
var studiors=adminDataProvider.GetPupilsBySchoolclassId(s.SchoolclassId);
s、 学生=学生;
foreach(小学生中的小学生p)
{
var documents=adminDataProvider.GetDocumentsByPupilId(p.Id);
p、 文件=文件;
}
}
返校;
}
如果我现在有一个私人setter,上面的聚合将不起作用


那我还有别的选择吗?还是我应该坚持我的加载技术?

是的,您有很多选择:

将学生添加到已创建的列表中

var pupils = adminDataProvider.GetPupilsBySchoolclassId(s.SchoolclassId);
s.Pupils.AddRange(pupils);

foreach (Pupil p in pupils)
{
   var documents = adminDataProvider.GetDocumentsByPupilId(p.Id);
   p.Documents.AddRange(documents);
}
请注意,公开
列表
是一种不好的形式-最好公开
集合
,尽管这样您将不得不逐个添加项目

如果你这样写你的男人:

public class Schoolclass
{
    public Schoolclass()
    {
        Pupils = new BindingList<Pupil>(); 
            // binding list descends from Collection<T> 

    }            

    public int SchoolclassId { get; set; }
    public string SchoolclassCode { get; set; }

    public Collection<Pupil> Pupils { get; private set; }
}
公共课堂
{
公立学校班级()
{
瞳孔=新绑定列表();
//绑定列表从集合中派生
}            
public int SchoolclassId{get;set;}
公共字符串类代码{get;set;}
公共集合{get;private set;}
}
当然,写这个和加载程序的方法有1000000多种。我喜欢偷懒。然后,当你只在有人要求学生时才加载它们

这是一个安全问题。即使使用私有setter,您的
列表
属性仍然是可变的

我无法直接设置您的属性:

myclass.products=newlist()

。。。但我可以修改它:

下面是一篇讨论C#中不同类型不变性的好文章:


我返回IEnumerable,因此无法执行。AddRange()这不是您的代码示例所具有的功能:)您还有其他选项。延迟加载是我的选择,如果加载程序在同一个程序集中,内部私有作用域可能会工作。为什么列表和集合不好?我从来没有读过。这是没有意义的。我更喜欢即时加载,因为我拥有的数据很小,而且我使用的WPF是关于数据绑定的。像我以前经历的那样,将学生集合插入选定的班级会导致绑定问题。最好的方法是返回IEnumerable,因为它是一个接口。List不错,只是将其公开。在这里阅读更多:这个链接真的不能被普遍使用。我的要求很低,所以我不需要覆盖任何东西。在我的情况下,列表是完全可以的。感谢wiki链接,它没有c#:P我只是想把eric lippert的帖子归类到我的直接私人setter问题中。你说我可以修改它。。。使用.Add()那么这对您合适吗?添加不会损害不变性吗?因为它没有改变/设置一个新的列表,所以我觉得它是不变的。
public class Schoolclass
{
    public Schoolclass()
    {
        Pupils = new BindingList<Pupil>(); 
            // binding list descends from Collection<T> 

    }            

    public int SchoolclassId { get; set; }
    public string SchoolclassCode { get; set; }

    public Collection<Pupil> Pupils { get; private set; }
}
var myClass = new SchoolClass();
myClass.Pupils.Add(new Pupil());