接上文,我们这次要提的是按位运算的实际应用。
Dim fis() As System.Reflection.FieldInfo = mT.GetFields(BindingFlags.Public Or _ BindingFlags.Static)
其中的BindingFlags.Public Or BindingFlags.Static 可以看到,有两个枚举进行了OR运算。大家都知道这代表或者的意思,那么如何从字段列表中过滤出Public或者Static呢,原理是什么呢?很明显,枚举的值是整数,那么传递进去的必然也是个整数。在继续了解查找项的原理之前先搞清楚按位运算是个什么回事的东西?
1 And 5 其中AND,OR,XOR都是二元运算符,即是说参数有两个,对于整数的AND OR运算,其实是二进制的运算
0001代表2的0次方=1
0010代表2的1次方=2
0101代表2的2次方加2的0次方=5
那么AND运算就是匹配1和5这2个参数,比较他们的每一位,如果都为1则将1返回到该结果位,而OR运算也是匹配位,凡是任意一个参数位上有1则返回1到结果位,最后XOR则是返回只有一个1的位(有两个1的不算),好,接着刚才的1 AND 5
0001
0101
0001由于第一位都是1,故返回1
Or运算
0001
0101
0101只要有1就返回
Xor运算
0001
0101
0100 只有1个1的才返回,两个1的不返回
顺带提下NOT运算,这是一元运算,它是对参数的位取反(即使有符号位)
说了那么多,大家一定不清楚这跟用枚举来查找列表有什么关系吧,别急,现在将上篇文章中的枚举的定义改成这样,把值改了。
枚举 EmItemType 值是二倍递增的
产品=1 ‘原来是0
半成品=2 ‘原来是1
原料=4 ‘原来是2
END Enum
你在界面绑定的时候希望不列出原料的,而只列出产品和半成品,调用INfolist的获取方法(注意,我这里是接上文的,如果对InfoList不清楚,请看上文的反射的项目实战。
InfoList.GeInfoList(EmItemType.产品 Or EmItemType.半成品)
很好,传进来的参数
1 or 2
0001
0010
0011(有1就返回)很明显结果是3
’文章的关键就在这里。我们可以知道到底调用的时候传进来的是那些参数的组合!
Public Shared Function GetQueryString(ByVal em As Integer)
Dim Qstr As New Text.StringBuilder
Dim IFLst As InfoList = tblItemType () ‘这里取得枚举的列表
For i As Integer = 0 To IFLst.Count - 1
If IFLst(i).Value And em Then
Qstr.Append("ItemType=")
Qstr.Append(IFLst(i).Value.ToString)
Qstr.Append(" or ")
End If
Next
Qstr.Remove(Qstr.Length - 3, 3)
Return Qstr.ToString
End Function
这里通过遍历IFLst列表里的Info对象
对它的每项进行如下运算
IFLst(i).Value And em
可以通过这个运算,判断IFLst(i).Value值是否与em有相同为1的位,有的话则不返回0,否则返回0,其中0代表false,则程序不会将其追加到查询字符串。
我们的查询字符串已经构造完毕了,这样就可以取得想要的数据了
后记:
在我们的实际项目中,启动程序后是从后台取出所有数据,比如调用存储过程,取出了SaleOrder和SaleOrderDetail两个结果集,然后通过ORM(对象关系映射)来将结果集加载到SaleOrderInfoList对象和SaleOrderDetailInfoLIst对象,(这个ORM是面向对象开发才有的,当然这是主流开发技术,我接下来会讲它),
对于DATASET里的TABLE进行FILTER相信谁都会用,对视图进行排序也很简单,但如果想对InfoList就行排序和筛选,那就需要单独实现,当然,不可能 ProductInfoList和SaleInfoList都去实现这个排序和筛选,而不是将功能放到了ProductInfoList和SaleInfoList他们的父类上去会更好。我们上面谈到的InfoList是被绑定上了combobox,那么如果绑定在网格而又要支持排序和筛选呢。需要另外实现啦,以后的专题会讲如何实现对象的排序和筛选(就像用DataView那么简单)
1。 反射的技术实践
2。 反射的项目实战,将枚举转换成列表的办法