Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#通用列表集值作为项目索引_C#_List_Linq - Fatal编程技术网

C#通用列表集值作为项目索引

C#通用列表集值作为项目索引,c#,list,linq,C#,List,Linq,我有以下课程 public class DataStore { public int index {get;set;} public string value {get;set;} } 然后我有一个这样的列表: var dataStoreList = new List<DataStore> { //Initialise with lots of objects } var dataStoreList=新列表 { //用很多对象初始化 } 现在我想用列

我有以下课程

public class DataStore
{
   public int index {get;set;}
   public string value {get;set;}
}
然后我有一个这样的列表:

var dataStoreList = new List<DataStore> 
{ 
    //Initialise with lots of objects 
}
var dataStoreList=新列表
{ 
//用很多对象初始化
}
现在我想用列表中的items索引填充
索引


我知道我可以使用for循环,但是有没有一个衬里可以用来做这个呢?也许linq有一个功能?我在谷歌上搜索了一些术语,但还没有找到任何有用的

我想您正在寻找
可枚举范围

var list = Enumerable
    .Range(0, 10)
    .Select(q => new DataStore { index = q })
    .ToList();
它将创建一个包含10个条目的列表。

您可以使用。它有一个提供索引值的重载

var values = new string[] { "foo", "bar", "baz" };

var dataStoreList = values.Select((v, i) => new DataStore { index = i, value = v }).ToList();

我要稍微吹毛求疵一下。听起来您想要的是一个项目列表,其中索引表示项目在列表中的位置。第一项是0,下一项是1,以此类推。这个要求非常重要,您正在为此编写代码

但结果是一个
列表
。如果列表的内容被修改,会发生什么?可以在末尾添加项目,插入中间,或删除。添加的项可能有不正确的索引或没有索引。或者您可以随时更改项目的索引

此外,如果同一对象位于多个列表中,会发生什么情况?它的索引在一个列表或另一个列表中可能是错误的

结果是没有任何东西强制执行索引的正确性。有什么方法可以解决这个问题

潜在的问题是,单个项目不“知道”它包含在列表中,或者它在列表中的位置。列表本身处于更好的状态,可以知道其中项目的索引

一种可能性是:

var positionOfItemInList = myList.IndexOf(item);
列表已经知道每个项目在其中的位置。以上内容将始终指示项目在列表中的位置

另一个选项是将
索引
属性设置为只读,在创建项时将其设置,然后将列表封装在另一个类中,使其仅作为只读集合公开。至少通过这种方式,您可以确保索引相对于一个列表是准确的。(您仍然可以将列表中的项目添加到另一个列表中,这样索引就没有意义了。)

但潜在的一点是,如果一个项目保持自己的指数,就会产生指数错误或毫无意义的风险

另外,孤立地查看类的人可能会想知道
Index
是什么。这是不清楚的,因为从技术上讲,
索引
在类本身的上下文中没有任何意义


由于一些澄清意图的评论而增加。这是看待底层需求的完全不同的方式

有时,当我们需要在Excel中对项目进行排序时,我们可能会首先添加一个额外的列,并用数字序列填充它,以便我们可以将其重新排序回原始顺序。这与添加
索引
属性时的操作类似

但在处理引用类型时,这通常是不必要的。下面是一个例子:

假设此对象表示一个测试结果,并且您有一个按不希望更改的顺序排列的测试结果列表:

public class TestResult
{
    public DateTime Completed { get; }
    public TimeSpan Duration { get; }
    public decimal Score { get; set; }
}
大多数时候,我们不需要对象上的额外属性来告诉我们它的顺序。它可能不是一个好的属性,因为它实际上根本没有描述考试分数。它只是描述对象在某个集合中的位置,该属性可能正确,也可能不正确

如果我们有这个列表,并且我们想按照某个特定的顺序对它进行操作呢?我们可以创建一个包含相同项目的新列表,而不是对其进行排序并重新排序

public void DoStuffWithListOfTestScores(List<TestResult> testResults)
{
    // testResults is in some specific order and we don't want to change it.

    AddBonusForFinishingFaster(testResults);

    // the order of testResults hasn't changed.
}

private void AddBonusForFinishingFaster(IEnumerable<TestResult> testResults)
{
    var fastestTen = testResults.OrderBy(result => result.Duration).Take(10);
    foreach (var result in fastestTen)
    {
        result.Score += 10;
    }
}
public void dostuff with ListofTestScores(列出测试结果)
{
//测试结果是按照特定的顺序排列的,我们不想改变它。
添加Bonus以完成主(测试结果);
//测试结果的顺序没有改变。
}
专用void AddBonusForFinishingFaster(IEnumerable testResults)
{
var fastestTen=testResults.OrderBy(result=>result.Duration).Take(10);
foreach(var结果为最快)
{
结果:得分+=10分;
}
}

我们还没有解决如何为每个项目添加索引的问题。我们已使问题消失,并避免添加可能不需要的属性。

为列表创建扩展方法并调用它。或者更好的方法是为列表创建和扩展方法,并传递一个选择器以访问索引属性。此列表中是否已经填充了
,或者是否也要填充该值?+
。选择()
。您可以使用累进值为我正在等待填充的
列表
@BrianRogers编制索引it@Jimi你能详细说明一下吗?