我似乎经常(在处理枚举时)做这样的事情:
.Select(x => new {
enumDesc = (
x.status == GoodStatus ? "Good!"
: x.status == BadStatus ? "Bad<angryface>"
: x.status == Unknown ? "no clue"
)
})
或
let enumDesc = (
x.status == GoodStatus ? "Good!"
: x.status == BadStatus ? "Bad<angryface>"
: x.status == Unknown ? "no clue"
)
有些问题最终会产生数十种这样的情况,就像我现在正在处理的项目一样。这样做很好,因为它可以被翻译成SQL case语句,因此它比实现后的迭代更快。但是,在我当前的项目中,我需要在多个地方/查询中执行此操作。有没有办法以高性能和可重用的方式(即,转换为SQL)执行此操作而不重构结构(例如将枚举移动到表中)?我还没能想出一个。如果我可以捕获或别名三元组的东西,那就足够了,或者制作一个表达式来选择&#34;来自常数或属性或某事......
答案 0 :(得分:0)
如果您愿意避免if
逻辑,请考虑以下事项:
我经常会看到C#中的开发人员倾向于使用DescriptionAttribute
并将其与扩展方法相结合来查找enum
值的描述值。
public enum Status
{
[Description("no clue")]
Unknown,
[Description("Good!")]
Good,
[Description("Bad<angryface>")]
Bad
}
public static class EnumExt
{
public static string Description<T>(this T source)where T : struct, IConvertible
{
if (!typeof (T).IsEnum)
{
throw new ArgumentException("T must be an enumerated type");
}
var fi = source.GetType().GetField(source.ToString());
var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : source.ToString();
}
}
这是一个有效的.NET Fiddle我快速拼凑起来证明这一点。
否则,如果您想在不使用属性的情况下将字符串映射到enum
值,我建议使用switch
代替...
答案 1 :(得分:0)
您可以使用实现Expression<Func<T, T2>>
的方法,请参阅下面的示例:
public enum Status
{
GoodStatus,
BadStatus,
Unknown
}
public class foo
{
public Status status;
}
public void Execute()
{
List<foo> list = new List<foo>
{
new foo
{
status = Status.BadStatus
},
new foo
{
status = Status.GoodStatus
},
new foo
{
status = Status.GoodStatus
},
new foo
{
status = Status.Unknown
}
};
var descStatus = list.Select(GetStatus).ToList();
}
public Expression<Func<foo, object>> GetStatus(foo _foo)
{
return x => new
{
enumDesc = _foo.status == Status.GoodStatus
? "Good!"
: _foo.status == Status.BadStatus
? "Bad<angryface>"
: _foo.status == Status.Unknown ? "no clue" : ""
};
}