C#:如何将字符串转换为 class 以在 "is" 操作中使用?
C#: How to convert string into class to use in an "is" operation?
假设 predicate.Or 基于字符串列表动态生成 sql where 子句。有没有办法重构它,这样我就不必对 case 语句进行硬编码?有没有办法摆脱 switch 语句并重构为 simpler/elegant foreach?
//contentTypes will ALWAYS have members that are the string class name of some classes in our project
//ex List<string> contentTypes = new List<string>{"News", "Photos", "Video", "Product"}
foreach (string t in contentTypes)
{
switch (t)
{
case "News":
predicate = predicate.Or(ci => ci is News);
break;
case "Photos":
predicate = predicate.Or(ci => ci is Photos);
break;
case "Video":
predicate = predicate.Or(ci => ci is Video);
break;
case "Product":
predicate = predicate.Or(ci => ci is Product);
break;
}
}
你绝对可以让它更干净:
foreach (string t in contentTypes)
{
Expression<Func<ContentItem, bool>> typePredicate = t switch
{
nameof(News) => ci is News,
nameof(Product) => ci is Photos,
nameof(Video) => ci is Video,
nameof(Product) => ci is Product,
_ => throw new InvalidOperationException($"Unexpected content type: '{t}'")
};
predicate = predicate.Or(typePredicate);
}
另一种选择是创建一个 Dictionary<string, Expression<Func<ContentItem, bool>>
然后只使用:
foreach (string t in contentTypes)
{
predicate = predicate.Or(typePredicates[t]);
}
(如果您想要比从索引器获得的 KeyNotFoundException
更清晰的异常,请使用 TryGetValue
。)
如果您要添加很多类型,您可以创建一个辅助方法来无缝创建字典。但我会坚持明确说明您 想要支持哪些类型。
假设 predicate.Or 基于字符串列表动态生成 sql where 子句。有没有办法重构它,这样我就不必对 case 语句进行硬编码?有没有办法摆脱 switch 语句并重构为 simpler/elegant foreach?
//contentTypes will ALWAYS have members that are the string class name of some classes in our project
//ex List<string> contentTypes = new List<string>{"News", "Photos", "Video", "Product"}
foreach (string t in contentTypes)
{
switch (t)
{
case "News":
predicate = predicate.Or(ci => ci is News);
break;
case "Photos":
predicate = predicate.Or(ci => ci is Photos);
break;
case "Video":
predicate = predicate.Or(ci => ci is Video);
break;
case "Product":
predicate = predicate.Or(ci => ci is Product);
break;
}
}
你绝对可以让它更干净:
foreach (string t in contentTypes)
{
Expression<Func<ContentItem, bool>> typePredicate = t switch
{
nameof(News) => ci is News,
nameof(Product) => ci is Photos,
nameof(Video) => ci is Video,
nameof(Product) => ci is Product,
_ => throw new InvalidOperationException($"Unexpected content type: '{t}'")
};
predicate = predicate.Or(typePredicate);
}
另一种选择是创建一个 Dictionary<string, Expression<Func<ContentItem, bool>>
然后只使用:
foreach (string t in contentTypes)
{
predicate = predicate.Or(typePredicates[t]);
}
(如果您想要比从索引器获得的 KeyNotFoundException
更清晰的异常,请使用 TryGetValue
。)
如果您要添加很多类型,您可以创建一个辅助方法来无缝创建字典。但我会坚持明确说明您 想要支持哪些类型。