传递检查如果不为null仍然分配为null

时间:2015-04-01 10:04:54

标签: c#

我创建了一个匹配方法,它基本上接受一个Person对象,调用一个地址服务,然后尝试首先尝试匹配,然后尝试匹配,然后如果它不起作用它连接房屋名称/编号与saon信息(平面1a等),看看是否有效。

如果确实找到匹配项,我需要在我的变量matchingAddress中存储匹配的地址,然后进一步处理该方法的其余部分,为清楚起见,我已将其排除在外。

问题

我认为我的lamda语句存在问题,在第二个IF上我正在调试的人使用if语句返回true并且我正在进入分配代码但是它是即使IF语句要检查它不是null,也被设置为null。

有谁能解释这里发生了什么?

private void AttemptMatch(Person person, string username)
        {
            var postcode = person.Postcode;

            List<JsonAddressModel> Addresses = _service.GetAddress(postcode); //returns a list of addresses for that persons postcode
            JsonAddressModel matchingAddress = new JsonAddressModel();

            //1.) Access the Service and see if theres a straight forward match
            if (Addresses.FirstOrDefault(x => x.paon.Trim() == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null)
            {
                matchingAddress = Addresses.First(x => x.paon.Trim() == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo);                
            }

            //2.) try and combine the paon and saon and see if that matches address line one            

            if (Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null)
            {
                matchingAddress = Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo).FirstOrDefault();
            }

            if (matchingAddress != null)
            {
                //rest of method to complete matching process for matched person         
            }

            else
                return;
        }

6 个答案:

答案 0 :(得分:2)

停止重复你已经完成的工作 1 ,然后删除一些条件逻辑:

//1.) Access the Service and see if theres a straight forward match
//if (Addresses.FirstOrDefault(x => x.paon.Trim() == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null)
//{
matchingAddress = Addresses.FirstOrDefault(x => x.paon.Trim() == person.AddressLineOne &&
                x.thorofare.Trim() == person.AddressLineTwo) ??                
//}

//2.) try and combine the paon and saon and see if that matches address line one            

//if (Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null)
//{
   /*matchingAddress = */
 Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) ==
              person.AddressLineOne &&
              x.thorofare.Trim() == person.AddressLineTwo).FirstOrDefault();              
//}

您当前的问题是由于在第二个if中,您没有调用任何选择方法(例如FirstOrDefaultToList等),所以您要检查的是查询是否为null而不是任何结果。


1 目前,您仅运行查询以确定它是否返回任何结果,然后再次运行查询 以实际获取这些结果。然后,你可能(如果你没有得到第二个if稍微错误)第二次做同样的技巧,使用它来覆盖以前的结果来启动,这是我相信你想要的实际结果。所以,相反,我们只运行一个查询,如果它返回null,我们使用??移动并尝试第二个查询。

答案 1 :(得分:1)

您输入if的原因是您没有在条件中调用FirstOrDefault()。与null进行比较的是Where方法的返回,该方法永远不会null

您可以通过将FirstOrDefault的结果存储在临时变量中来优化代码,然后仅在不是null时分配它:

var tmp1 = Addresses.FirstOrDefault(x => x.paon.Trim() == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo);
if (tmp1 != null) {
    matchingAddress = tmp1;                
}
var tmp2 = Addresses.FirstOrDefault(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo);
if (tmp2 != null) {
    matchingAddress = tmp2;
}

答案 2 :(得分:1)

尝试更改此内容:

Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null

有关

Addresses.Any(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null

理想情况下,如果你不满意的话。你的SingleOrDefault应该可以做到这一点。

基本上,Where永远不会返回null,它只返回一个空的IEnumerable

答案 3 :(得分:1)

永远不会返回null值。您需要检查返回的集合是否为空。

我认为最好的选择是将“where”改为“any”

if (Addresses.Any(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo))

答案 4 :(得分:0)

这个linq正在返回集合,它始终不为null。它可以是空的但永远不会为空。

试试这个:

if (Addresses.Any(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo))
{
matchingAddress = Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo).FirstOrDefault();
}

它将检查是否有任何匹配的项目。

答案 5 :(得分:0)

您可以在第二个尝试此操作:

        if (Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo).FirstOrDefault() != null)
        {
            matchingAddress = Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo).FirstOrDefault();
        }

'Addresses.Where(filter)'返回null是不可能的。当IEnumerable<T>中的所有元素都不满足where过滤器时,它将返回空IEnumerable<T>