C#中如何在表达式树中对同一对象属性使用空合并运算符?
问题:表达式树场景下高效合并同一对象的属性值
给定以下类定义:
class User{ long Id; string FirstName; string Nickname; }
class Location{ List<User> Users; }
需求是根据条件从列表中获取用户,优先使用其Nickname,若Nickname为空则用FirstName。常规写法如下:
User selectedUser = locationObj.Users.First(u => u.Id == 1); string nameToBeCalledBy = selectedUser.Nickname ?? selectedUser.FirstName;
但当前场景需要处理不支持语句体的表达式树,目前能想到的替代写法会两次调用First(),既低效又不优雅:
locationObj.Users.First(u => u.Id == 1).Nickname ?? locationObj.Users.First(u => u.Id == 1).FirstName
想知道是否存在更优雅的写法,能对同一对象的属性进行空合并操作,类似伪代码:
locationObj.Users.First(u => u.Id == 1).(Nickname ?? FirstName)
解决方案
方法1:先投影再取结果
通过LINQ的Where筛选后直接用Select处理属性合并,最后调用First(),这样只遍历一次列表,避免重复查询:
string nameToBeCalledBy = locationObj.Users .Where(u => u.Id == 1) .Select(u => u.Nickname ?? u.FirstName) .First();
如果用查询表达式写法会更直观:
var nameToBeCalledBy = (from u in locationObj.Users where u.Id == 1 select u.Nickname ?? u.FirstName).First();
方法2:封装扩展方法复用逻辑
给User类添加扩展方法,把属性合并的逻辑封装起来,后续直接调用即可:
public static class UserExtensions { public static string GetDisplayName(this User user) { return user.Nickname ?? user.FirstName; } }
在表达式树中使用时只需一次First()调用:
string nameToBeCalledBy = locationObj.Users.First(u => u.Id == 1).GetDisplayName();
这种方式既保证了效率,又让代码更具可读性和复用性。
内容的提问来源于stack exchange,提问作者geisha-and-guis
相关产品推荐
相关产品推荐

