Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.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#存取器和集合_C#_Collections - Fatal编程技术网

C#存取器和集合

C#存取器和集合,c#,collections,C#,Collections,定义类时,我将类成员作为属性公开,如下所示: class ClassA { private String _Name; public String Name { get { return _Name; } set { _Name = value; } } } 关于访问器,处理类内集合的最佳实践是什么 因此,如果将该类扩展为: class ClassA { private String _Name; privat

定义类时,我将类成员作为属性公开,如下所示:

class ClassA
{
    private String _Name;

    public String Name
    {
        get { return _Name; }
        set { _Name = value; }
    }
 }
关于访问器,处理类内集合的最佳实践是什么

因此,如果将该类扩展为:

class ClassA
{
    private String _Name;
    private List<String> _Parts = new List<String>();

    public String Name
    {
        get { return _Name; }
        set { _Name = value; }
    }
 }
A类
{
私有字符串\u名称;
私有列表_Parts=新列表();
公共字符串名
{
获取{return\u Name;}
设置{u Name=value;}
}
}

如何公开下一项?

公开集合的只读实例。请注意,内容不是只读的,而是引用

public IList部分{get;private set;}

除了列表,你就不能这样做吗

public List<String> parts
    {
        get { return _Parts; }
        set { _Parts = value; }
    }
公共列表部件
{
获取{return\u Parts;}
设置{u Parts=value;}
}

我也会公开属性

public List<string> Parts { get; set; }
公共列表部分{get;set;}

我遇到的命名约定推荐

private String _name;
您还可以使用自动属性生成与您编写的代码相同的代码

public string Name {get; set;}
对于集合,我不喜欢公开实际的集合,而是公开处理它的方法

public void Add(...
public void Remove(...
否则,可以使用自动属性将其设置为只读

public IList<string> Parts {get; private set;}
public IList部分{get;private set;}

这取决于您对封装数据存储方式的重视程度。如果您正在做一个轻量级类,并且您只是提供了存储,但是希望将访问决策完全留给类的使用者,那么您只需将其作为标准属性公开,或者将其作为自动属性

public List<String> Parts { get; private set; }
公共列表部分{get;private set;}
如果要确保变量从不为null,请继续使用您的专用支持字段并添加检查

private List<String> _Parts;
public IList<String> Parts
{
    get
    {
        if (_Parts == null)
            _Parts = new List<String>();
        return _Parts;
    }
    private set
    {
        if (value != null)
            _Parts = value;
    }
}
private List\u零件;
公共部分
{
得到
{
如果(_Parts==null)
_零件=新列表();
返回零件;
}
专用设备
{
if(值!=null)
_零件=价值;
}
}
但是,如果您想要控制同步或其他类似的操作,您应该公开对您所做的操作具有逻辑性的方法

public void AddPart(String part);
public void RemovePart(String part);
public String GetPart(int index);
public IEnumerable<String> GetAllParts()
{
    foreach(String part in _Parts)
        yield return part;
}
public void AddPart(字符串部分);
公共无效删除部分(字符串部分);
公共字符串GetPart(int索引);
公共IEnumerable GetAllParts()
{
foreach(字符串部分在_部分中)
屈服返回部分;
}

我不知道是否有具体的最佳做法,但有两件事要考虑。基本方法与其他人所说的相同:

public List<String> Parts
{
    get { return _Parts; }
    private set { _Parts = value; }
}
公共列表部件
{
获取{return\u Parts;}
私有集{u Parts=value;}
}
这里的要点是确保
\u Parts
永远不为
null
。这导致了微妙而难以发现的bug

但是,如果需要在添加和删除元素时发送事件,则只有两个选项:

  • 使用List的子类在适当时发送事件
  • 根本不公开列表,只公开
    AddPart()
    RemovePart()
    ListParts()
    (返回当前列表的副本)

如果您的需求很简单,只需公开该属性(但要保护它不被分配
null
)。否则,您将不得不更加花哨。

您有很多选择,这实际上取决于您希望向类的公共API开放什么类型的操作。最常见的方法是:

  • 提供只读属性以返回具有相同类型信息的实际集合实例
  • 提供返回
    IEnumerable
    接口的只读属性
  • 提供一个只读属性,该属性返回集合的
    ReadOnlyCollection
    包装

同样,这实际上取决于您希望如何公开集合,但上述3个选项在大多数情况下都可以正常工作。如果您有更特殊的要求,例如允许从公共API添加集合,同时不允许删除,那么事情会变得更复杂。

我们通常会执行以下操作:

private Collection<String> _parts = new Collection<String>();
public Collection<String> Parts {
  get { return _parts; }
}
private Collection\u parts=new Collection();
公共收集零件{
获取{return\u parts;}
}

这样可以确保在创建对象时实例化集合,并使_parts集合的基础引用为只读。这意味着您可以添加/删除零件,但不能更改属性指向的对象。

public IList会更好。嗯。如果我很挑剔,我会说使用IEnumerable,除非你有很好的理由不这样做。它将与字符串完全相同…尽管我建议如果你在.net 3.5上使用自动属性!可以,但它必须是
public List Parts
您是指小写的p吗?@Eric,对于迭代器块,返回类型应该是
IEnumerable
而不是
List
@Anthony是的,您是对的。我很匆忙,因为我看到其他人很快就回答了!谢谢。这取决于你的物品是收藏还是有收藏。例如,winforms控件不是其子控件的集合,但DataGridViewRowCollection肯定是。
private Collection<String> _parts = new Collection<String>();
public Collection<String> Parts {
  get { return _parts; }
}