说我有以下类结构
public class EmailActivity {
public IEnumerable<MemberActivity> Activity { get; set; }
public string EmailAddress { get; set; }
}
public class MemberActivity {
public EmailAction? Action { get; set; }
public string Type { get; set; }
}
public enum EmailAction {
None = 0,
Open = 1,
Click = 2,
Bounce = 3
}
我希望基于EmailActivity
的存在来过滤MemberActivity
对象的列表,其中{null}与提供的EmailAction
匹配项列表匹配的非空EmailAction
。我只想将EmailAddress属性返回为List<string>
。
据我所知
List<EmailAction> activityTypes; // [ EmailAction.Open, EmailAction.Bounce ]
List<string> activityEmailAddresses =
emailActivity.Where(
member => member.Activity.Where(
activity => activityTypes.Contains(activity.Action)
)
)
.Select(member => member.EmailAddress)
.ToList();
但是我收到一条错误消息“ CS1503参数1:无法从'EmailAction转换?”到“ EmailAction””
如果然后修改activityTypes
以允许空值List<EmailAction?>
,我将得到以下信息:“ CS1662无法将lambda表达式转换为预期的委托类型,因为该块中的某些返回类型不能隐式转换为委托返回类型”。
问题是嵌套的.Where
返回列表,但是父级.Where
需要布尔结果。我该如何解决这个问题?
我意识到我可以使用嵌套循环,但是我想提高我的C#技能!
答案 0 :(得分:1)
就性能而言,使用List.Contains
并不理想,HashSet
是一个更好的选择,如果您希望在包含搜索到的操作之一时立即选择电子邮件地址,则可以使用Any
:
var activityTypes = new HashSet<EmailAction>() { EmailAction.Open, EmailAction.Bounce };
List<string> activityEmailAddresses =
emailActivity.Where(
member => member.Activity.Any(
activity => activity.Action.HasValue &&
activityTypes.Contains(activity.Action.Value)
)
)
.Select(activity => activity.EmailAddress)
.ToList();
答案 1 :(得分:0)
您想使用All
还是Any
取决于您是否希望每场比赛或至少一场比赛...
HashSet<EmailAction> activityTypes = new HashSet<EmailAction> { EmailAction.None };
var emailActivity = new List<EmailActivity>
{
new EmailActivity { Activity = new List<MemberActivity>{ new MemberActivity { Action = EmailAction.None } }, EmailAddress = "a" },
new EmailActivity { Activity = new List<MemberActivity>{ new MemberActivity { Action = EmailAction.Click } }, EmailAddress = "b" }
};
// Example with Any but All can be used as well
var activityEmailAddresses = emailActivity
.Where(x => x.Activity.Any(_ => _.Action.HasValue && activityTypes.Contains(_.Action.Value)))
.Select(x => x.EmailAddress)
.ToArray();
// Result is [ "a" ]