【问题标题】:C# Passing arrays between class A and Class BC# 在 A 类和 B 类之间传递数组
【发布时间】:2011-06-18 18:09:33
【问题描述】:

我正在尝试将 array[i] 从 B 类转到我的 A 类。

在 B 类我有:

public array getArray() {
    return array[i];
}

我怎样才能获得完整的array 来完成这项工作?

combobox1.items.add(getArray());

我正在尝试这个,但它不起作用。您能否用一个代码示例来回答,该示例解释了不同类中发送和获取array[i] 的两种方法。

【问题讨论】:

  • 这个问题的一些可怕答案。

标签: c# arrays class methods


【解决方案1】:

您需要让class A 访问整个数组,而不仅仅是单个值。例如

class B {
  Object[] _array;
  public Object[] GetArray() {
    return _array;
  }
}

现在class A 可以使用所有元素并完全填充组合框

foreach (object element in classBInstance.GetArray()) {
  combobox1.Items.Add(element);
}

【讨论】:

  • 这很脏。在面向对象的世界中,你永远不应该直接返回你的内部数组。 -1
  • @Al 用户似乎对该语言相当陌生,因此我选择了最直接的解决方案。
  • 实际上最直接的代码是一个属性: public Object[] MyArray { get;私人套装; } 在 B 类中。
  • @knight0323 我会避免这样做,因为它使用了更高级的语言功能。
  • 好吧,我想这里的每个人都有一些道理。
【解决方案2】:

你的例子你有 i 但它没有在任何地方启动,你需要像这样传递它:

public array getArray(int i)
{
    return array[i];
}



combobox1.items.add(getArray(5));

【讨论】:

  • 同上:这是脏的。在面向对象的世界中,您永远不应该直接返回您的内部数组。 -1
【解决方案3】:

你的问题不是很清楚,所以我会尝试根据我理解的你的问题来回答。

class A 
{
    string[] array;
    public string[] GetArray() { return array; }
}

然后你可以编写这样的代码来填充组合框

A items = new A();
// fill in array in A
comboBox1.DataSource = items.GetArray();

foreach(string item in items)
{
    comboBox1.Items.Add( item );
}

我确实一直使用DataSource 成员设置列表,尤其是从enums 到字符串时。

示例:

comboBox1.DataSource = System.Enum.GetNames(typeof(System.DayOfWeek));

【讨论】:

  • 同上:这是脏的。在面向对象的世界中,您永远不应该直接返回您的内部数组。 -1
  • @AlKepp 当您关心速度时您会这样做,而不必每秒复制 10,000 次值。不是每个人都在构建需要这种安全级别的银行代码。抛开我的 OOP 理想主义,现实地回答所提出的问题。
【解决方案4】:

你必须遍历你的数组:

foreach(var item in GetArray())
{
     combobox1.Items.Add(item);
}

【讨论】:

  • 好吧,如果我理解正确的话 foreach(var item in ClassB.GetArray()) { combobox1.Items.Add(item); } 参考classb?
  • 同上:这是脏的。在面向对象的世界中,您永远不应该直接返回您的内部数组。 -1
【解决方案5】:

虽然其他答案在技术上是可行的,但在我看来,永远不应该直接返回内部数组,因为它违背了面向对象编程的良好实践。因此,我要么在该类中实现 IEnumerable 接口,要么至少返回 IEnumerator 或 IEnumerable,这将使返回的集合成为只读。

例子:

class ClassB {
  int[] array;
  public IEnumerable<int> GetValues() { return array; }
}

class ClassA {
  void DoTheJob(ClassB source) {
    foreach(int item in source.GetValues()) {
      combobox.Items.Add(item);
    }
  }
}

另一个干净的解决方案是向 B 类添加“使用值”功能。然后我们只需提供委托。示例:

class ClassB {
  int[] array;
  public void DoWithValues(Action<int> action) {
    foreach(int item in array) action(item);
  }
}

class ClassA {
  ComboBox combobox;
  void DoTheJob(ClassB source) {
    source.DoWithValues(item => combobox.Items.Add(item));
  }
}

下一个(第三个)示例展示了如何使用 foreach 使整个 ClassB 可枚举:

static void Main(string[] args) {
  ClassB b = new ClassB();
  foreach(int i in b) Console.Write(i + " ");
}

class ClassB : IEnumerable<int> {

  int[] array;

  public ClassB() {
    array = new int[20];
  }

  public IEnumerator<int> GetEnumerator() {
    return (array as IEnumerable<int>).GetEnumerator();
  }

  IEnumerator IEnumerable.GetEnumerator() {
    return array.GetEnumerator();
  }
}

更新: 正如 ja72 所示,这种简单的技术只是发布内部数组的枚举数,并没有物理隐藏数组,因为生成的 IEnumerator 可以被强制转换回 int[]。

更新 #2: 我的兄弟总是使用 Clone() 返回数组的副本。这是最慢的,但他说这几次挽救了他的职业生涯(他在一个团队中从事一个更大的项目)。

【讨论】:

  • 你能展示一个 IEnumerable 接口的示例吗,因为我用谷歌搜索过,但从来没有得到一个直接的答案
  • Ivan,如果你有内部数组,你可以将它作为 IEnumerable 返回。在我的第一个示例中查看方法 GetValues()。这是最简单的方法。我将在第三个示例中展示另一种可能性(使整个 B 类可枚举)。
  • -1。您的代码假定 class A 是一个包装器(只能有一个它表示的集合/数组)或者它返回数组(掩蔽为 IEnumarable&lt;&gt; 仍然可以破坏原始数组并且违反 OOP 原则(根据您的 cmets)。你总是可以做int[] list = (int[])GetValues()
  • 在不了解 Ivan 的代码的情况下,此示例散发出不必要的复杂性。
  • @ja72:我的代码不假设类中只有一个数组。 Ivan 只是让我展示如何让整个类可枚举,我展示了最简单的方法。你的另一个抱怨更有趣。是的,这是一个经典的问题:如果提供的枚举器可以转换回数组类型,它是否正确?事实上,继承不应该被用作一种保护技术。如果你想在物理上隐藏它可以回滚的事实,我可以提供另一个使用 yield 命令的例子。
猜你喜欢
  • 2019-11-18
  • 1970-01-01
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 1970-01-01
  • 2014-03-20
  • 2013-07-22
  • 1970-01-01
相关资源
最近更新 更多