当从列表中删除引用的对象时,c# 复制的属性丢失引用

标签 c# linq properties reference

示例

看看下面的代码:

private void DeDuplicateOrganisations()
{
     var profileOrgs = _organisations.Where(o => o.ExistsInProfile).ToList();
     var kvkOrgs = _organisations.Where(o => !o.ExistsInProfile).ToList();

     profileOrgs.ForEach(o =>
         {
             var duplicate = kvkOrgs.FirstOrDefault(k => k.KvK == o.KvK || k.Title == o.Title);
             if (duplicate != null)
             {
                  o.CompanyInfoOrganisation = duplicate.CompanyInfoOrganisation;
                  o.ExistsInBoth = true;
                  kvkOrgs.Remove(duplicate);
              }
           });

      _organisations = profileOrgs.Concat(kvkOrgs).OrderBy(o => o.Title).ToList();
}

在这个例子中,属性CompanyInfoOrganisation(只是一个get;set;property)在一个组织被认为是重复的时候被复制。这一切都按预期工作,重复项被很好地删除了。

这条消息也是如此:
_organisations.First(o => o.ExistsInBoth).CompanyInfoOrganisation != null;

问题

现在我将 _organisations 列表绑定(bind)到列表框

lbxCompanies.DataSource = null;
lbxCompanies.DataSource = _organisations;
lbxCompanies.DisplayMember = "Title";
lbxCompanies.SelectedIndex = -1;

然后获取选定的值:

 var org = lbxCompanies.SelectedValue as Organisation;
 gbxCompanyInfo.Visible = org != null;
 if (gbxCompanyInfo.Visible)
    if (org.CompanyInfoOrganisation != null)
          // NEVER GETS HERE (but gbxComanpyInfo is visible)

如果我尝试读取 CompanyInfoOrganisation 属性,我总是得到 null,而我知道该属性已设置。

问题

这里发生了什么?为什么属性引用被破坏了?我怎样才能防止这种情况发生?

最佳答案

您正在使用的引用仅具有直接作用域,一旦查询结束,它就会退出作用域并且您的引用也会消失。所以当你稍后绑定(bind)时,引用是完全正确的——null。

profileOrgs.ForEach(o =>
{
    // Right here -- var duplicate has scope ONLY within your query. 
    // As soon as the query is executed it leaves scope and the reference
    // pointer will be null
    var duplicate = kvkOrgs.FirstOrDefault(k => k.KvK == o.KvK || k.Title == o.Title);
    if (duplicate != null)
    {
        o.CompanyInfoOrganisation = duplicate.CompanyInfoOrganisation;
        o.ExistsInBoth = true;
        kvkOrgs.Remove(duplicate);
    }
});

因为您正在使用一个类,所以您需要执行深度 MemberwiseClone在它上面获取对象的新副本:

o.CompanyInfoOrganisation = (YourInfoType)duplicate.CompanyInfoOrganisation.MemberwiseClone();

关于当从列表中删除引用的对象时,c# 复制的属性丢失引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11431878/

相关文章:

java - 如何正确避免特定的 UITableViewCell 可编辑?

c# - 使用 GZipStream 解压缩 .gz 文件

c# - Linq2Sql 和 lambda 返回 "Method ' System.Object DynamicInvoke(System.Object[] )' has no supported translation to SQL"

c# - LINQ to XML 查询中的格式错误

c# - 将带有子查询的sql查询转换为linq语句

java - 如何从属性中删除键并保持原始顺序?

c# - WPF 动画未触发

c# - Windows 10 iot (Raspberry PI3 - ARM) 上的 .net 核心安装

c# - 如何使用 linq 从列表中查找具有相同项目的最后一项