List<T> 将 foreach 循环中的所有项目覆盖为最后一个值
Posted
技术标签:
【中文标题】List<T> 将 foreach 循环中的所有项目覆盖为最后一个值【英文标题】:List<T> overwrites all the items inside a foreach loop to the last value 【发布时间】:2015-07-04 17:00:13 【问题描述】:我正在尝试构建一个 Windows 应用程序,其中有一个组合框,并且在 Load() 期间,我用我的 app.Config 文件中可用的所有连接字符串填充这个组合框。
这里是app.Config sn-p:
<!-- Adding Multiple Servers in Connection String-->
<connectionStrings>
<add name="SQLConnect-1"
connectionString="Data Source=SAHIL; Initial Catalog=RecordComparisonTool; Integrated Security=SSPI"
providerName="System.Data.SqlCLient"/>
<add name="SQLConnect-2"
connectionString="Data Source=SAHIL; Initial Catalog=RecordComparisonTool; User Id=test; Password=12123; Integrated Security=SSPI"
providerName="System.Data.SqlCLient"/>
<add name="SQLConnect-3"
connectionString="Data Source=SAHIL; Initial Catalog=RecordComparisonTool; User Id=test; Password=32315; Integrated Security=True"
providerName="System.Data.SqlCLient"/>
</connectionStrings>
我创建了一个 CompareResult 类,我在其中尝试从 app.Config 中获取所有值并将其显示到组合框。
namespace RecordComparisonTool_Win
public class ConnectionString
public string name get; set;
public string conString get; set;
public string provider get; set;
public class CompareResult
public List<ConnectionString> GetConnection()
List<ConnectionString> conStr = new List<ConnectionString>();
ConnectionString conn = new ConnectionString();
foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings)
if (!(css.Name == "LocalSqlServer" || css.Name == "LocalmysqlServer"))
conn.name = css.Name;
conn.conString = css.ConnectionString;
conn.provider = css.ProviderName;
conStr.Add(conn);
return conStr;
问题是当我尝试将它与组合框绑定时,它根据 app.Config 文件显示三个记录,但所有记录的值都与“SQLConnect-3”相同。对于所有记录,我无法找到使用“SQLConnect-3”更新列表的原因。请帮助修复错误。这是我将此列表绑定到 ComboBox 的 sn-p
protected void LoadConnection()
CompareResult compareResult = new CompareResult();
List<ConnectionString> connectionString = new List<ConnectionString>();
connectionString = compareResult.GetConnection();
cbTokenLeft.DataSource = connectionString;
cbTokenLeft.DisplayMember = "name";
cbTokenLeft.ValueMember = "conString";
【问题讨论】:
更新:根据下面提到的答案,我在 foreach() 循环之外实例化 ConnectionString 的对象时犯了一个错误,并且每次都会覆盖数据。通过在 foreach() 循环中实例化它,问题得到了解决。谢谢大家的解决方案。 【参考方案1】:这个:
conn.name = css.Name;
conn.conString = css.ConnectionString;
conn.provider = css.ProviderName;
conStr.Add(conn);
每次迭代都会覆盖您的 ConnectionString
引用。您需要在每个循环中分配一个新的ConnectionString
:
foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings)
if (!(css.Name == "LocalSqlServer" || css.Name == "LocalMySqlServer"))
var conn = new ConnectionString
name = css.Name;
conString = css.ConnectionString;
provider = css.ProviderName;
conStr.Add(conn);
【讨论】:
【参考方案2】:将ConnectionString conn = new ConnectionString();
行移到最里面的循环内。它是一个参考类,您一遍又一遍地将同一个实例添加到您的列表中。
public List<ConnectionString> GetConnection()
List<ConnectionString> conStr = new List<ConnectionString>();
foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings)
if (!(css.Name == "LocalSqlServer" || css.Name == "LocalMySqlServer"))
ConnectionString conn = new ConnectionString();
conn.name = css.Name;
conn.conString = css.ConnectionString;
conn.provider = css.ProviderName;
conStr.Add(conn);
return conStr;
【讨论】:
【参考方案3】:由于您要在循环之外实例化 ConnectionString
,因此所有迭代都使用(并覆盖)相同的实例。您需要在循环中在中实例化它,以便每次迭代都会获得一个新实例:
foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings)
if (!(css.Name == "LocalSqlServer" || css.Name == "LocalMySqlServer"))
ConnectionString conn = new ConnectionString();
conn.name = css.Name;
conn.conString = css.ConnectionString;
conn.provider = css.ProviderName;
conStr.Add(conn);
您也可以使用 LINQ 表达相同的代码:
var conStr =
(
from css in ConfigurationManager.ConnectionStrings
where !(css.Name == "LocalSqlServer" || css.Name == "LocalMySqlServer")
select new ConnectionString
name = css.Name,
conString = css.ConnectionString,
provider = css.ProviderName,
).ToList();
【讨论】:
以上是关于List<T> 将 foreach 循环中的所有项目覆盖为最后一个值的主要内容,如果未能解决你的问题,请参考以下文章
C#中list<>定义的变量,我用foreach()循环查找 与 list<> .find 查找两个哪个效率高?后者是不是用了算法