【问题标题】:c#, Get index of current T in List<T>c#, 获取 List<T> 中当前 T 的索引
【发布时间】:2019-02-05 14:13:13
【问题描述】:

我搜索了很多,我可能偶然发现了一些类似的东西,但对我来说仍然是陌生的,因为我是 c# 的新手。

我想从 List 中获取对象 Tline 的当前索引 我知道我可以简单地用一个 int i 进行迭代。但我不明白为什么或如何在不搜索任何内容的情况下将其作为 当前 iteam 的索引。

Tline 有点像

public class Tline
    {
        public string Cd_m { get; set; }           
        public string cd_d { get; set; }
        public string cd_c { get; set; }
       ...
    }

我的问题在这里(用箭头表示)

  class ACCS 
{
    internal void DBwrite(List<Tline> imoprtati)
    {
        OleDbConnection myAccessConn = null;

        string sFld = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        string dbName = "EDIM1.mdb";
        dbName = Path.Combine(sFld, dbName);
        string accessConn = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", dbName);

        string sqlQuery = "INSERT INTO DOTes (`id`,`cd_m`,`cd_d`,`cd_c`,`nume`) values (?,?,?,?,?)";

        myAccessConn = new OleDbConnection(accessConn);
        int i = 2;
         foreach (var insT in imoprtati)
         {
            using (OleDbCommand cmd = new OleDbCommand(sqlQuery, myAccessConn))
            {
                cmd.Connection.Open();

                cmd.Parameters.AddWithValue("@id", i.ToString());
                cmd.Parameters.AddWithValue("@cd_m", "2018");
                cmd.Parameters.AddWithValue("@cd_d", "BO");
                cmd.Parameters.AddWithValue("@cd_c", "C00128");

                //  Show current Tline  Index                           ↓↓↓↓↓↓↓
                cmd.Parameters.AddWithValue("@nume", (imoprtati.GetEnumerator().Current)); //trying anything
                cmd.ExecuteNonQuery(); 


                cmd.Connection.Close();
                i++;

            }
         }
    }

}

【问题讨论】:

  • 你试过imoprtati.IndexOf(Current)吗?
  • 在此使用for 循环可能会更好,因为您需要索引和关联项
  • @vc74 实际上可能不是(至少,如果你是一个书呆子的话)——由于List&lt;T&gt; 的自定义结构迭代器与索引器相比,它可能会更昂贵一些使用for;如果这是一个数组:你绝对正确
  • List不保证顺序。如果您想避免奇怪的事情,您应该考虑将其更改为SortedList
  • @MarcGravell 感谢您提到这一点,for 循环可能比foreach 慢。我想这会给那些相信“永远不要使用 foreach,它比 for 慢”的 OP 造成更多的混乱。但如果要处理的项目数量很大,我只会考虑这个论点,如果不是这种情况,我会选择可读性而不是微优化。

标签: c# arraylist


【解决方案1】:

imoprtati.GetEnumerator().Current 不起作用,因为您正在创建一个具有自己位置的 separate 迭代器(当前在第一项之前)。您最好的选择可能是一个简单的计数器:

int index = 0;
foreach (var insT in imoprtati) {
    // your stuff here...


    index++;
}

一个包含索引的 LINQ 方法,但由于自定义结构迭代器、捕获的变量等(复杂的主题),最终效率会降低。

【讨论】:

  • 谢谢,我不知道!我已经删除了我之前的评论。
【解决方案2】:

List.GetEnumerator().Current 将为列表创建一个新的枚举器,然后返回当前的item,而不是索引。如您所见,这将不起作用。

由于 List 实现了 IList,您可以使用 IndexOf(T item);方法来查找项目的基于 0 的索引。

https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ilist-1.indexof?view=netframework-4.7.2#System_Collections_Generic_IList_1_IndexOf__0_

但是,此方法不能保证恒定的 O(1) 性能,因为它必须搜索列表。一个更好的选择是在您按照您所说的那样遍历它们时记录索引。

如果不记录索引,就无法在恒定时间内找到列表中任意项的索引,所以我建议这样做。

【讨论】:

  • 遍历所有项目并搜索每个项目的索引保证产生 n * (n + 1) 扫描,与其他建议相比,这绝对不是最佳解决方案在这个页面上。
  • 我提出了与其他答案相同的解决方案,同时提供了替代方案,并指出了缺点。 OP直接询问如何获取任意列表项的索引。你就是这样做的。
  • 我只是强调你的替代方案确实更好:)
  • @WayneGore “OP 直接询问如何获取任意列表项的索引” - 不,他们询问如何获取正在迭代的 current 项的索引 - 不是完全一样的东西;他们还用粗体字说“不搜索任何东西”
  • @MarcGravell 是的,我似乎确实误会了他的意图。谢谢指正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多