Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.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# 如何检查对象';s字段是否存在于给定对象的列表中?_C#_.net_List - Fatal编程技术网

C# 如何检查对象';s字段是否存在于给定对象的列表中?

C# 如何检查对象';s字段是否存在于给定对象的列表中?,c#,.net,list,C#,.net,List,我有两个班,一个叫记录,一个叫位置 public class Record { public string Id { get; set; } } public class Location { public string LocationId { get; set; } public bool isDefault { get; set; } } 现在我需要检查位置列表中是否存在来自记录的给定ID。例如,这是我迄今为止处理的代码。如果当前列表中不存在field.

我有两个班,一个叫记录,一个叫位置

public class Record
{
        public string Id { get; set; }
}

public class Location
{
    public string LocationId { get; set; }
    public bool isDefault { get; set; }
}
现在我需要检查位置列表中是否存在来自记录的给定ID。例如,这是我迄今为止处理的代码。如果当前列表中不存在field.Id,则应创建一个新位置并将其添加到列表中

foreach (Record field in inputs)
            {
                locationResponse = await myLocationCmd.GetLocation(locationInput).ConfigureAwait(false);
                
                foreach (Location locations in locationResponse.Locations)
                {
                        if (locations.IsDefault == true)
                        {
                            this.BadRequest();
                        }
                        else if (locations.IsDefault == false && // Check whether field.Id exists in locationResponse.Locations)
                        {
                            locationInput.Verb = CmdletVerb.Set.ToString();
                        }
                        else if (locations.IsDefault == false && // Check whether field.Id does not exist in the locationResponse.Locations)
                        {
                            locationInput.Verb = CmdletVerb.New.ToString();
                        }
                 
                }

目前我尝试执行
locationResponse.Locations.Contains(field.Id)
,但这会产生一个类型错误。有人知道这样做的正确方法吗?

如果我理解正确,您需要在每个对象上循环检查ID

locationResponse.Locations.Contains(field.Id)
给出了一个类型错误,因为这是位置列表,而不是字符串列表

locationResponse = await myLocationCmd.GetLocation(locationInput).ConfigureAwait(false);

foreach (Record field in inputs) {
    var idExists = false;
    foreach (Location loc in locationResponse.Locations)
        idExists = loc.LocationId == field.Id;
        if (idExists) break;
    }
    Console.WriteLine(idExists);
}

不过,对于
输入
列表的大小,我会保持谨慎,因为每个字段都会多次查看相同的位置列表,这是浪费迭代次数

基于给定代码的最短修复方法是使用:

bool idExistsInList = locationResponse.Locations.Any(location => location.LocationId == field.Id);
然后您可以使用
idExistsInList
!在您的两条注释中分别列出idExistsInList


但是,还需要做一些进一步的改进:

  • 您的代码中有一个bug。内部foreach会一直覆盖相同的值,并且只会有效地保留在
    foreach
    的最后一个循环中设置的值
  • 同样的错误也发生在您的外部
    foreach
    上。通过比较两个列表的最后一个元素,可以有效地定义
    locationInput.Verb的值,并有效地覆盖所有其他求值
  • 一般来说,LINQ优于手动
    foreach
    逻辑。它提高了可读性,减少了模板制作
  • 假设这是外部
    foreach
    中唯一的逻辑,也可以使用LINQ简化
  • 对于每个输入字段,您获取相同的
    locationResponse
    。如果没有实际使用特定字段值来获取对象,那么对每个字段执行此操作是没有意义的
  • 无需进行第三次
    if
    评估。当前两次评估失败时,第三次评估总是正确的
  • ==true
    始终可以忽略
  • ==false
    通常应重构为使用
  • 当您总是设置相同的字段/属性,但布尔值决定了您是否将其设置为一个值或另一个值时,是否喜欢使用三元
    myBool?valueIfTrue:ValueIfValse
您可以在
foreach
循环之外提取此逻辑:

var locationResponse = await myLocationCmd.GetLocation(locationInput).ConfigureAwait(false);

if(locationResponse.Locations.Any(location => location.IsDefault))
    this.BadRequest();

var locationIds = locationResponse.Locations.Select(location => location.LocationId).ToList();
如何处理
foreach
循环尚不清楚,因为我不确定您是否正在尝试查找位置列表中是否有任何字段(=至少一个)匹配,或者是否每个字段都在位置列表中匹配

如果您试图查找位置列表中是否有任何字段(=至少一个)匹配:

bool matchFound = inputs.Any(field => locationIds.Contains(field.Id);
bool matchFound = inputs.All(field => locationIds.Contains(field.Id);
如果要查找位置列表中是否每个字段都有匹配项:

bool matchFound = inputs.Any(field => locationIds.Contains(field.Id);
bool matchFound = inputs.All(field => locationIds.Contains(field.Id);
Any
如果至少有一个字段匹配,则返回
true
All
如果所有字段都匹配,则仅返回
true

在任何一种情况下,您都可以继续:

locationInput.Verb = matchFound
                        ? CmdletVerb.Set.ToString()
                        : CmdletVerb.New.ToString();

这与您的代码相同,但冗余更少,可读性更高。

不清楚您的意思。
Id
字段将始终作为对象的属性存在。它可以是null,也可以是空字符串,尽管我试图传达的是列表中的每个Location对象都有一个LocationID。如果列表中已存在与字段ID相比的LocationId,则它将是一个Set命令。如果列表中不存在与位置ID相比的字段ID,则将创建一个新位置并将其添加到列表中。我希望更清楚的是,不要给GetLocation
一个ID,然后作为响应的一部分返回,这样所有位置都已经有了正确的ID?GetLocation接受另一个类,当提供一个ID时,它将返回与该ID关联的所有位置。现在在这个特定场景中并不重要。