替代多个 if 语句的 Lambda 表达式
Lambda expression alternative to several if statements
我正在尝试完成一个表达式函数替代
private static Expression<Func<UserProfile, bool>> CompareFilter(FilterViewModel f)
{
...
}
关于这个:
private static bool CompareFilter(UserProfile profile, FilterViewModel filter)
{
if (filter.FirstName != null)
{
if (profile.FirstName != null)
{
if (profile.FirstName.CompareTo(filter.FirstName) != 0)
{
return false;
}
}
else
{
return false;
}
}
if (filter.TownId != null)
{
if (profile.TownId != filter.TownId)
{
return false;
}
}
// true if at least one of the filter interests match
if (filter.InterestsIds != null)
{
var firstInterestFound = profile.Interests
.Where(i => filter.InterestsIds.Contains(i.Id))
.FirstOrDefault();
if (firstInterestFound == null)
{
return false;
}
}
...
return true;
}
有没有办法让这么多嵌套的 if 语句适合 lambda 表达式或其他适用于表达式函数的东西?这个想法是通过所有 if 语句进行验证,并且仅当所有语句都不是 return 时才 return 为真。
提前致谢!
首先,你现在的方法这么长是因为你没有很好地利用布尔逻辑。可以简化为:
private static bool CompareFilter(UserProfile profile, FilterViewModel filter)
{
if (filter.FirstName != null && filter.FirstName != profile.FirstName)
{
return false;
}
if (filter.TownId != null && filter.TownId != profile.TownId)
{
return false;
}
// true if at least one of the filter interests match
if (filter.InterestsIds != null &&
!profile.Interests.Any(i => filter.InterestsIds.Contains(i.Id)))
{
return false;
}
...
return true;
}
你可以把它变成一个笨重的大表达式 by inverting all the logic1:
private static bool CompareFilter(UserProfile profile, FilterViewModel filter)
{
return (filter.FirstName == null || filter.FirstName == profile.FirstName) &&
(filter.TownId == null || filter.TownId == profile.TownId) &&
(filter.InterestsIds == null ||
profile.Interests.Any(i => filter.Interests.Contains(i.Id)));
// etc. etc.
}
一旦你有了这个,把它变成一个 lambda 并得到你的 Expression<T>
:
private static Expression<Func<UserProfile, bool>> CompareFilter(FilterViewModel f)
{
return profile =>
(filter.FirstName == null || filter.FirstName == profile.FirstName) &&
(filter.TownId == null || filter.TownId == profile.TownId) &&
(filter.InterestsIds == null ||
profile.Interests.Any(i => filter.Interests.Contains(i.Id)));
}
- 从技术上讲,您可以
||
将第一种方法中的所有条件放在一起,并在其周围放置一个大的 !( )
:return !( (...) || (...) || (...));
,但是将所有内容反转并加入条件 &&
好多了。
我正在尝试完成一个表达式函数替代
private static Expression<Func<UserProfile, bool>> CompareFilter(FilterViewModel f)
{
...
}
关于这个:
private static bool CompareFilter(UserProfile profile, FilterViewModel filter)
{
if (filter.FirstName != null)
{
if (profile.FirstName != null)
{
if (profile.FirstName.CompareTo(filter.FirstName) != 0)
{
return false;
}
}
else
{
return false;
}
}
if (filter.TownId != null)
{
if (profile.TownId != filter.TownId)
{
return false;
}
}
// true if at least one of the filter interests match
if (filter.InterestsIds != null)
{
var firstInterestFound = profile.Interests
.Where(i => filter.InterestsIds.Contains(i.Id))
.FirstOrDefault();
if (firstInterestFound == null)
{
return false;
}
}
...
return true;
}
有没有办法让这么多嵌套的 if 语句适合 lambda 表达式或其他适用于表达式函数的东西?这个想法是通过所有 if 语句进行验证,并且仅当所有语句都不是 return 时才 return 为真。
提前致谢!
首先,你现在的方法这么长是因为你没有很好地利用布尔逻辑。可以简化为:
private static bool CompareFilter(UserProfile profile, FilterViewModel filter)
{
if (filter.FirstName != null && filter.FirstName != profile.FirstName)
{
return false;
}
if (filter.TownId != null && filter.TownId != profile.TownId)
{
return false;
}
// true if at least one of the filter interests match
if (filter.InterestsIds != null &&
!profile.Interests.Any(i => filter.InterestsIds.Contains(i.Id)))
{
return false;
}
...
return true;
}
你可以把它变成一个笨重的大表达式 by inverting all the logic1:
private static bool CompareFilter(UserProfile profile, FilterViewModel filter)
{
return (filter.FirstName == null || filter.FirstName == profile.FirstName) &&
(filter.TownId == null || filter.TownId == profile.TownId) &&
(filter.InterestsIds == null ||
profile.Interests.Any(i => filter.Interests.Contains(i.Id)));
// etc. etc.
}
一旦你有了这个,把它变成一个 lambda 并得到你的 Expression<T>
:
private static Expression<Func<UserProfile, bool>> CompareFilter(FilterViewModel f)
{
return profile =>
(filter.FirstName == null || filter.FirstName == profile.FirstName) &&
(filter.TownId == null || filter.TownId == profile.TownId) &&
(filter.InterestsIds == null ||
profile.Interests.Any(i => filter.Interests.Contains(i.Id)));
}
- 从技术上讲,您可以
||
将第一种方法中的所有条件放在一起,并在其周围放置一个大的!( )
:return !( (...) || (...) || (...));
,但是将所有内容反转并加入条件&&
好多了。