C# 列表中的屈服项
在我的应用程序中,有一个仅带getter的C# 列表中的屈服项,c#,yield,C#,Yield,在我的应用程序中,有一个仅带getter的列表: public List<MyItem> myList { get { MyHost.GetItemFromID(_i1); //this may be a long operation MyHost.GetItemFromID(_i2); MyHost.GetItemFromID(_i3); MyHost.GetItemFromID(_i4);
列表
:
public List<MyItem> myList
{
get
{
MyHost.GetItemFromID(_i1); //this may be a long operation
MyHost.GetItemFromID(_i2);
MyHost.GetItemFromID(_i3);
MyHost.GetItemFromID(_i4);
MyHost.GetItemFromID(_i5);
}
}
公共列表myList
{
得到
{
MyHost.GetItemFromID(_i1);//这可能是一个很长的操作
MyHost.GetItemFromID(i2);
MyHost.GetItemFromID(_i3);
MyHost.GetItemFromID(i4);
MyHost.GetItemFromID(_i5);
}
}
此列表有时需要作为一个整体进行检索,而其他时候只需要访问某些项目:即
myList[3]
。有没有办法不构建整个列表,因为我只需要第四项?您可以返回IEnumerable
并使用:
请注意,如果顺序无关紧要,并且只有第一次调用GetItemFromID
比其他调用花费更多的时间,那么最好更改执行顺序:
yield return MyHost.GetItemFromID(_i2);
yield return MyHost.GetItemFromID(_i3);
yield return MyHost.GetItemFromID(_i4);
yield return MyHost.GetItemFromID(_i5);
yield return MyHost.GetItemFromID(_i1); //this may be a long operation
我想我误解了这个要求。我把“有时我只需要第四项”读作“只需要四项” 因此,您可以使用我的aproach,但要使用
元素at
:
MyItem fourthItem = MyItems.ElementAt(3);
如果您不知道是否有第四个用法
ElementAtOrdefault
您可以用一个类来包装列表,比如说“myListContainer”,并重载其“[]”操作符,这样您就可以执行以下操作:
myListContainer[3]
var myItems = GetItems(_i2, _i3, _i5).ToList();
哪个将调用该调用
MyHost.GetItemFromID(_i3);
并返回所需的列表项
如果需要,我将添加一个完整的示例
编辑
public class myListContainer
{
public MyItem this[int i]
{
get
{
return MyHost.GetItemFromID(i);
}
}
}
并添加方法以获取整个列表。注意:
这假设“第四项”是指序号,而不是实际id本身。
提前建立一张地图,只返回你想要的物品
List<int> map = new List<int>
{
_i1,
_i2,
_i3,
_i4,
_i5,
};
public IEnumerable<MyItem> myList(params int[] indices)
{
if (!indices.Any())
return map.Select(MyHost.GetItemFromID);
return indices.Select(i => MyHost.GetItemFromID(map[i]));
}
// so you call
myList(); // for all items; decide on this API, may be separate to two methods?
myList(0); // or
myList(4); // or
myList(1, 3); // all loaded only on demand
列表映射=新列表
{
_i1,
_i2,
_i3,
_i4,
_i5,
};
公共IEnumerable myList(参数int[]索引)
{
如果(!index.Any())
返回map.Select(MyHost.GetItemFromID);
返回索引。选择(i=>MyHost.GetItemFromID(map[i]);
}
//所以你打电话
myList();//适用于所有项目;决定这个API,可以分为两种方法吗?
myList(0);//或
myList(4);//或
myList(1,3);//全部仅按需加载
如果您想对索引进行更多控制,请使用字典。理想情况下,出于某种原因,您应该一次性将所有ID传递给DB,如果是这样的话,SQL直接处理它。我不知道
\u i1
等的密钥是什么类型的,但让我们假设它们是INT。然后你可以这样做:
public IEnumerable<MyItem> GetItems(params int[] keys)
{
return keys.Select(key => MyHost.GetItemFromID(key));
}
或
等等
注意:如果您只希望返回列表,则可以在GetItems()
本身中进行转换:
public List<MyItem> GetItems(params int[] keys)
{
return keys.Select(key => MyHost.GetItemFromID(key)).ToList();
}
公共列表GetItems(参数int[]键)
{
return keys.Select(key=>MyHost.GetItemFromID(key)).ToList();
}
不过,这种方法需要方法而不是属性。这很好。这假设传递的是实际的id,应该转到
GetItemFromID
函数。从OP上看不太明显。@nawfal同意-可能需要OP的澄清。这仍然需要加载客户不感兴趣的不需要的ID。@nawfal:你是对的,我误解了“有时我只需要第四项”。我把它读作“只需要四个项目”ElementAt在索引之前不会仍然遍历所有项目吗?换句话说,您的方法在传递的参数之前运行ID的GetFromID调用。@这不是OP后面的内容。虽然LINQ的代码看起来很酷;)@nawfal:true,它仍然需要调用allGetItemFromID
。所以我个人更喜欢barakcaf的MyListContainer类apporach。
var myItems = GetItems(_i2, _i3, _i5).ToList();
var myItems = GetItems(_i3).ToArray();
public List<MyItem> GetItems(params int[] keys)
{
return keys.Select(key => MyHost.GetItemFromID(key)).ToList();
}