【问题标题】:C# Return an object from a list based on indexC#根据索引从列表中返回一个对象
【发布时间】:2012-02-24 13:41:34
【问题描述】:

我需要进行一些更改,以便一次只从列表中检索一个对象,而不是像现在这样检索整个列表。

现在,我在 B 类中有一个私有列表,其中一个属性返回整个列表,基本上无论如何都将其公开,我想更改它。

a 类的外观(使用列表操作的 ui 类)是,我输入一些数据验证它并将其发送到 B 类,然后 B 类根据输入将其打包成一个对象列表。

然后A类需要循环这个列表并将它添加到一个列表视图中以显示它,目前看起来像这样:

    ListViewItem lvi = new ListViewItem();
        foreach ([Object] o in CLassB.getList())
        {
            lvi = new ListViewItem(o.property0);
            lvi.SubItems.Add(o.property1);
            lvi.SubItems.Add(o.property2);
            lvi.SubItems.Add(o.property3);
        }
    }

Object 是我的抽象类,它控制如何添加不同类型的项目,getList() 是我在 B 类中返回整个列表的方法。

问题是这些属性是所有类共享的公共属性,但也有一些不是,例如您输入有关对象的特定文本的文本框等,其显示如下:

    private void lvRegistered_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
    {
        if (Listview.SelectedItems.Count > 0)
        {
            foreach ([Object] ob in ClassB.getList())
            {
                if (Listview.SelectedItems[0].SubItems[0].Text == ob.id.ToString())
                {
                    TextBox.Clear();
                    TextBox.Text = ob.property4;
                }
            }
        }
    }

现在这一切都很好,但现在我有一个返回的列表要操作,但我不想返回列表使其公开我想根据索引号返回列表的一个对象(是的功能将完全相同,我创建了一个返回私有列表计数的方法,因此我可以遍历它并返回所有)。这是为了在我不想返回所有内容时练习 OOP。

如何做到这一点?我能想到的只是创建一个新列表,将 int 作为输入并搜索我的私人列表并找到索引,然后将其添加到另一个列表并返回该列表,但我不知道这是好的做法还是最好的方法去做吧?好吧,我还没有研究如何将一个元素“复制”到下一个列表,但不妨检查一下是否有更好的方法来做事?

这种方式让我感觉自己“走了很长一段路”

【问题讨论】:

  • 所以只公开ClassB.GetItemByIndex(int index) 而不是ClassB.getList(),或者你的问题是什么?
  • 您可以使用 list.AsReadOnly() 方法 (goo.gl/Ue1kA)。

标签: c# list


【解决方案1】:

不太清楚,但是简单的GetById 方法怎么样?

public class Foo
{
    public int Id { get; set; }

    public string Name { get; set; }
}

public class Test
{
    private List<Foo> list = new List<Foo>();

    public void Add(Foo foo)
    {
        this.list.Add(foo);
    }

    public Foo GetById(int id)
    {
        return this.list.FirstOrDefault(z => z.Id == id);
    }
}

....

Test test = new Test();
test.Add(new Foo { Id = 1, Name = "1" });
test.Add(new Foo { Id = 2, Name = "2" });
test.Add(new Foo { Id = 3, Name = "3" });

Foo foo2 = test.GetById(2);

【讨论】:

  • 是的,这看起来可行,已经有一个 id。我看到的唯一问题是我序列化和反序列化我的列表,所以如果我要删除 id 3,例如,我可以从 1 开始执行一个 forloop 并计算列表的计数以查找 id`s,必须以某种方式修复它。
【解决方案2】:

我不确定我是否完全理解,但听起来你可以通过在 B 类上创建一个索引器来返回你想要的项目来解决这个问题:

public object this[int index] {
  get {
    return list[index];
  }
}

将“对象”更改为您的实际类类型。

然后您可以像 B 类是一个数组一样访问这些项目:

object item = classB[5];

【讨论】:

    【解决方案3】:

    1) 可以使用 List.AsReadOnly() 方法。

    public ReadOnlyCollection<Double> MyList {
            get {
                return myList.AsReadOnly();
            }
    }
    private List<Double> myList;
    

    2) 在类中使用索引方法。

    public Double this[int index] {
            get {
                return myList[index];
            }
            set {
                myList[index] = value;
            }
     }
    private List<Double> myList;
    

    【讨论】:

    • asreadonly 的问题是它仍然返回整个列表,对吗?关键是要使(即使对于这个特定的任务我想返回everyhting)列表检索我允许的内容,说我存储敏感数据或其他东西,然后每个人都不能访问列表中的所有内容,只是指定的数据搜索。
    【解决方案4】:

    按照 Ken2k 的建议做了差不多的事情,但我选择了这个:

        public [Class] getListItem(int index)
        {
            return myList.ElementAt(id);
        }
    

    这又在我的其他类中使用,显示如下信息:

        for (int i = 0; i < am.getCount(); i++)
                {
                    ListViewItem = new ListViewItem([class reference].getList(i).[property].ToString());
                    ListViewItems.SubItems.Add([class reference].getList(i).[property]);
                }
    

    感谢大家为此提供的所有帮助。

    【讨论】:

      猜你喜欢
      • 2013-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-05
      • 1970-01-01
      相关资源
      最近更新 更多