我在使用索引器处理对象列表时遇到了一些麻烦。我希望能够通过它的名称(字符串)而不是它的索引来访问列表中的每个对象。所以,我想重载[]运算符来实现这一点。到目前为止,我无法在智能感知中显示过载,此时它无法正常工作。到目前为止我所拥有的是:
一个名为MapInfo的类的单例对象:
MapInfo mi = MapInfo.Instance;
在MapInfo类中,我有一个Table对象列表:
List<Table> tables;
public List<Table> Tables
{
get { return tables; }
}
最后在Tables类中我尝试过这个:
class Table : IEnumerable<Table>
{
public Table this[string tableName]
{
get
{
foreach (Table table in this)
{
if (table.name == tableName)
return table;
}
return null;
}
}
我希望能够使用以下方式访问我的Table对象:
mi.Tables["SomeTableName"]
这是我第一次尝试这个,所以我不太确定我哪里出错了。
答案 0 :(得分:1)
您正在重载Table类的索引器。你的代码结构出了问题。 Table类是IEnumerable<Table>
,因此Table包含其他表。
因此,List<Table>
将包含Table实例,而Table实例又包含Table实例。
使用mi.Tables["SomeTableName"]
,您尝试访问List的索引器,而不是Table的索引器。
为什么不在MapInfo中定义索引器?
答案 1 :(得分:1)
使用字典
Private Dictionary<String, Table> tables;
public Dictionary<String, Table> Tables
{
get { return tables; }
}
然后:
class Table : IEnumerable<Table>
{
public Table this[string tableName]
{
get
{
Table table;
if(mi.tables.TryGetValue(tableName, out table))
{
return table;
}
else
{
return null;
}
}
}
}
答案 2 :(得分:1)
你可以使用这样的方法
public class MapInfo {
private readonly TableCollection _tables = new TableCollection();
public TableCollection Tables {
get { return _tables; }
}
}
public class TableCollection : List<Table> {
public Table this[string name] {
get { return this.FirstOrDefault(t => t.Name == name); /*using System.Linq;*/ }
}
}
public class Table {
public string Name { get; set; }
}
或简单地使用字典(Dictionary<string, Table>
),如Danaldo建议的那样。但不是他们两个,因为他编码=))
IMO,正确的方法是不要使用像这样的索引器,因为我看到有多个表可以使用&#39; unique&#39;您的收藏中的名称。我建议使用一个简单的表列表和一个像GetTableWithName这样的方法来使事情变得更清楚,因为索引器通常会给(假)你的数据是唯一的
或者您可以将FirstOrDefault
的来电替换为SingleOrDefault
,这将在内部确保如果有一个名为&#39;的名称&#39;没有其他元素具有相同的名称&#39;
答案 3 :(得分:0)
您对MapInfo / Table的实施并不适合让您做您想做的事。
MapInfo中Table的属性不能是表的列表,它必须是Table类型。然后你的Table类应该完全实现IEnumerable接口。 用LinqPad编写的快速示例:
class Table : IEnumerable<Table>
{
public Table()
{
_tables = new Dictionary<string, Table>();
}
public string name { get; set; }
Dictionary<string, Table> _tables;
public void Add(string tname)
{
_tables.Add(tname, new Table { name = tname });
}
public Table this[string tableName]
{
get
{
Table table;
if (_tables.TryGetValue(tableName, out table))
return table;
return null;
}
}
public IEnumerator<Table> GetEnumerator()
{
return _tables.Values.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
void Main()
{
MapInfo mi = new MapInfo();
mi.Table["foo"].Dump();
}
class MapInfo
{
public MapInfo()
{
Tables = new Table();
test();
}
private void test()
{
Tables.Add("foo");
Tables.Add("bar");
Tables.Add("soom");
}
public Table Tables { get; set; }
}