【问题标题】:What happens with properties and arrays in C#?C# 中的属性和数组会发生什么?
【发布时间】:2012-04-25 02:14:40
【问题描述】:

好的,我有这门课和主课。我正在使用 VS 2010 Ultimate 和 .NET 4 客户端。

internal class tezt
{
    private int[] _numeros = new int[5];
    public int[] Numeros
    {
        get { return _numeros; }
    }
}
public class tezt2
{
    private int[] _numeros = new int[5];
    public int[] Numeros
    {
        get { return _numeros; }
    }
}
class tezt3
{
    private int[] _numeros = new int[5];
    public int[] Numeros
    {
        get { return _numeros; }
    }
}
internal static class Program
{
    private static void Main()
    {
        var arrNums = new tezt();
        var arrNums2 = new tezt2();
        var arrNums3 = new tezt3();
        Console.WriteLine(arrNums.Numeros[0]);
        arrNums.Numeros[0] = 5;
        Console.WriteLine(arrNums.Numeros[0]);
        Console.WriteLine(arrNums2.Numeros[0]);
        arrNums2.Numeros[0] = 6;
        Console.WriteLine(arrNums2.Numeros[0]);
        Console.WriteLine(arrNums3.Numeros[0]);
        arrNums3.Numeros[0] = 7;
        Console.WriteLine(arrNums3.Numeros[0]);
        Console.ReadKey(true);
    }
}

这些行发生了什么:

arrNums.Numeros[0] = 5;
arrNums2.Numeros[0] = 6;
arrNums3.Numeros[0] = 7;

难道不是因为派生这些对象的类没有set参数,就不能允许这些赋值?

可以做些什么来避免这种情况,限制这种情况,像arrNums.Numeros[0] = 5; 这样的行为会引发错误?

【问题讨论】:

  • 您没有设置属性。您正在从属性中获取数组并分配给它的元素。如果您不想这样做,请不要公开数组。

标签: c# arrays properties


【解决方案1】:

您没有设置Numeros 属性,您正在修改该属性内索引处的元素。您只为该属性使用 getter

不允许的分配是为该对象的属性分配一个新值:

arrNums.Numeros = new int[5]; // will not compile.

你可以让 getter 返回一个 IEnumerable<int> 来保护它:

class tezt3
{
    private int[] _numeros = new int[5];
    public IEnumerable<int> Numeros
    {
        get { return _numeros; }
    }
}

您也可以使用ReadOnlyCollection。使用IEnumerable&lt;T&gt;ReadOnlyCollection&lt;T&gt; 的优缺点在this question 中进行了深入讨论。

【讨论】:

  • 快速提问,如果我正在使用您的代码,并且我还想通过 set 参数将元素分配给 _numeros,我该如何完成?
  • 您也可以提供一个设置基础集合的 setter:set { _numeros = value.ToArray(); }
  • Aja,现在,当我分配一些东西时,我说arrNums.Numeros = new[] {5};,如果我之前是arrNums.Numeros = new[] {5, 6, 7, 8, 9};,元素6、7、8和9将会丢失。无论如何要避免这种情况?
  • 编写一个Add 方法将项目添加到集合中
  • 这将是一个只有get 的属性,就像答案中一样
【解决方案2】:

我也可以建议不要在属性上使用数组。这是Framework Design Guidelines的引述

返回数组的属性可能会产生很大的误导。通常是 需要返回内部数组的副本,以便用户 不能改变内部状态。这可能会导致代码效率低下。

在以下示例中,Employees 属性在 循环的每次迭代。那将是 2n + 1 个副本 以下短代码示例:

Company microsoft = GetCompanyData("MSFT");
for (int i = 0; i < microsoft.Employees.Length; i++)
{   
  if (microsoft.Employees[i].Alias == "kcwalina")
  {  ...  }
}

Brad Abrams,本书的注释者,评论这个陷阱:

本书中的一些指导方针在 抽象的;其他人是在艰苦的学校里学到的。这 返回数组的属性的指导方针是困难的 敲阵营。当我们调查一些性能问题时 在 .NET Framework 1.0 版中,我们注意到数以千计的数组 正在被创建并迅速被丢弃。原来很多地方 在 Framework 本身就遇到了这种模式。不用说,我们 修复了这些实例和指南。 - 布拉德艾布拉姆斯

【讨论】:

    猜你喜欢
    • 2016-04-05
    • 2012-05-27
    • 2013-10-03
    • 2014-07-28
    • 2018-08-08
    • 1970-01-01
    • 2017-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多