说我有这样的课程:
class From
{
public bool FlagOne { get; set; }
public bool FlagTwo { get; set; }
public bool FlagThree { get; set; }
}
...我希望将这些列表转换为以下列表:
class To
{
public List<Flag> Flags { get; set; }
}
... Flag
看起来像这样:
public enum Flag
{
One,Two,Three
}
我写了一些代码:
var froms = new List<From>
{
new From {
FlagOne = false,
FlagTwo = true,
FlagThree = true
},
new From {
FlagOne = true,
FlagTwo = false,
FlagThree = true
}
};
var tos = froms.Select(from => new To {
Flags = // ....... what? what goes here?
}).ToList();
枚举值的名称和布尔标志无关紧要。应该没有必要的反思。
我有一个这样的数据库表:
+---------+---------+-----------+
| FlagOne | FlagTwo | FlagThree |
+=========+=========+===========|
| 0 | 1 | 1 |
+---------+---------+-----------+
| 1 | 0 | 1 |
+---------+---------+-----------+
我希望制作一个如下所示的界面:
+-------------------------------------+
| Lorem blahdiblah FlagTwo, FlagThree |
+-------------------------------------+
| Lorem blahdiblah FlagOne, FlagThree |
+-------------------------------------+
我没有 来做这件事;我只是认为用LINQ解决这是一个有趣的问题,并且无法找到答案。
答案 0 :(得分:3)
处理此问题的一种方法是在集合中使用可为空的Flag
,然后过滤掉null
s,如下所示:
var tos = froms
.Select(f => new To {
Flags = new[] {
f.FlagOne ? (Flag?)Flag.One : null,
f.FlagTwo ? (Flag?)Flag.Two : null,
f.FlagThree ? (Flag?)Flag.Three : null
}
.Where(f => f.HasValue)
.Select(f => f.Value)
.ToList()
}).ToList();
在Flags
赋值中创建的数组有三个Flag?
类型的项目 - 每个标志一个。对应于未设置属性的标志变为null
s;与set属性对应的标志变为可为空Flag.XYZ
。
其余的很简单:Where()
过滤掉null
,Select()
删除可空性,最后ToList()
将结果列为一个列表。
答案 1 :(得分:1)
为什么要转换它?
您也可以在枚举中实现标记:
[Flags]
public enum Foo : int {
Bit1 = 0x01,
Bit2 = 0x02,
Bit3 = 0x04
}
然后,您可以通过按位AND操作检查标志是否处于活动状态。例如:
Foo aVariable = Foo.Bit1|Foo.Bit3;//both bit1 and bit3 are enabled
检查bit3是否已启用:
if((aVariable&Foo.Bit3) != 0x00) {
//flag is enabled, now do something
}
else {
//flag is disabled, do something else
}
使用这种结构的优点是位表示更紧凑,操作(如按位OR)可以更快地处理,您不必担心位的语义(枚举隐藏实际值比特)。
如果您真的想要枚举可能的值,可以使用通用构造:
public static class Bar {
public static IEnumerable<T> EnumerateAtoms<T> (this T input) where T : enum {
foreach(T value in Enum.GetValues(typeof(T))) {
if((input&val) != 0x00) {
yield return value;
}
}
}
}
答案 2 :(得分:0)
To ConvertFromFromToTo(From from)
{
List<Flag> flags = new List<Flag>();
if (from.FlagOne) flags.Add(Flag.One);
if (from.FlagTwo) flags.Add(Flag.Two);
if (from.FlagThree) flags.Add(Flag.Three);
return new To { Flags = flags };
}
var tos = froms.Select(ConvertFromFromToTo).ToList();
答案 3 :(得分:0)
目前还不清楚你打算如何将旗帜bool映射到枚举值,但你可能想要使用这样的东西:
Flags = new List<Flag> {
from.FlagOne ? Flag.One : Flag.Two,
from.FlagTwo ? Flag.One : Flag.Two,
from.FlagThree ? Flag.One : Flag.Two }
主要问题是你想要Flag.One,Flag.Two和Flag.Three来表示。