一组用户权限由n个bool值组成
将他们排成一个二进制形式的数字
例如:
ture false t f f t t t f f f f 对应
1     0    1 0 0 1 1 1 0 0 0 0
然后将这个二进制的数字转换成一个10进制的整数以便于存储。
然后转换回来,做业务层的判断。希望不要进行太多的类型转换,尤其是string类型的转换。尽量使用元数据类型。刚开始做觉得没那么难 一动手发现一点思路都没有请各位赐教,求具体实现代码。谢谢!

解决方案 »

  1.   

    用位操作吧!根据你的编码就可以实现啊!
    1、设置位的操作    /// <summary>
        /// 设置位(假定源为一个字节)
        /// </summary>
        /// <param name="src">源数据(一个字节内有效)</param>
        /// <param name="pos">第几位</param>
        /// <param name="value">值</param>
        /// <returns>设置后的值</returns>
        private int SetBit(int src, int pos, bool value)
        {
            int c=0;
            if (value)
            {
                switch (pos)
                {
                    case 1: c = 1; break;
                    case 2: c = 2; break;
                    case 3: c = 4; break;
                    case 4: c = 8; break;
                    case 5: c = 16; break;
                    case 6: c = 32; break;
                    case 7: c = 64; break;
                    case 8: c = 128; break;
                }
                c = c | src;
            }
            else
            {
                switch (pos)
                {
                    case 1: c = 0xfe; break;
                    case 2: c = 0xfd; break;
                    case 3: c = 0xfb; break;
                    case 4: c = 0xf7; break;
                    case 5: c = 0xef; break;
                    case 6: c = 0xdf; break;
                    case 7: c = 0xbf; break;
                    case 8: c = 0x7f; break;
                }
                c = c & src;
            }
            return c;
        }
    2、判断位的操作:    /// <summary>
        /// 判断位的值(假定源为一个字节)
        /// </summary>
        /// <param name="src">源数据(一个字节)</param>
        /// <param name="pos">第几位</param>
        /// <returns>该位为0还是为1,如果是1返回真,否则返回假</returns>
        private bool CheckBit(int src,int pos)
        {
            int c=0;
            switch (pos)
            {
                case 1: c = 1; break;
                case 2: c = 2; break;
                case 3: c = 4; break;
                case 4: c = 8; break;
                case 5: c = 16; break;
                case 6: c = 32; break;
                case 7: c = 64; break;
                case 8: c = 128; break;
            }       
            
            return (c & src)>0;
        }
      

  2.   

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                bool[] barray = new bool[] { false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true};            int res = ConvertBoolArrayToInt(barray); // bool数组转int值            Console.WriteLine("binary:{0:18}",Convert.ToString(res,2));            int len = barray.Length;
                bool[] barray2 = ConvertIntToBoolArray(res, len);            Console.WriteLine("bytearray:");
                for (int i = 0; i < len; i++)
                {
                    Console.Write("{0},",barray2[i]);
                }
                Console.ReadKey();
            }        private static int ConvertBoolArrayToInt(bool[] barray)
            {
                int result = 0;
                if (barray != null)
                {
                    int len = barray.Length;                if (len < 33)
                    {
                        foreach (bool b in barray)
                        {
                            result = (result << 1) + (b ? 1 : 0);
                        }                }
                    else
                    {
                        Console.WriteLine("bool数组长度大于32,整数只有32位。");
                        
                    }
                }
                else
                {
                    Console.WriteLine("bool数组为空。");
                    
                }            return result;
            }        private static bool[] ConvertIntToBoolArray(int result, int len)
            {            if (len > 32 || len < 0)
                {
                    Console.WriteLine("bool数组长度应该在0到32之间。");
                }            bool[] barray2 = new bool[len];            for (int i = 0; i < len; i++)
                {
                    barray2[len - i - 1] = ((result >> i) % 2) == 1;
                }            return barray2;
                
            }    }
    }
      

  3.   

    输出binary:10101010101010101
    bytearray:
    False,True,False,True,False,True,False,True,False,True,False,True,False,True,Fal
    se,True,False,True,
      

  4.   

    这么处理的一个问题是从int值不能直接推断出来byte[]的长度。如果把byte[]变成0101这种字符串的形式存入数据库,应该比较好。
    或是用一个long,64位,前6位写入byte数组的长度。后58位来存放byte[]。
      

  5.   


    如果对应的是0001111这样的,你保存的int就是1111,反过来读取的时候前面的3个值就没了啊
    我觉得还是转成string比较好
      

  6.   

    如果权限个数固定的话,可以参考如下代码:        //权限个数
            int priorityCount = 4;        /// <summary>
            /// 将BitArray转成int
            /// </summary>
            /// <param name="arr"></param>
            /// <returns></returns>
            private int GetIntValue(BitArray arr)
            {
                int number = 0;
                for (int i = arr.Length - 1; i >= 0; i--)
                {
                    number <<= 1;
                    if (arr[i])
                    {
                        number++;
                    }
                }
                return number;
            }        /// <summary>
            /// 将int转成BitArray
            /// </summary>
            /// <param name="number"></param>
            /// <returns></returns>
            private BitArray GetBitArray(int number)
            {
                BitArray tempArray = new BitArray(new int[] { number });
                BitArray returnArray = new BitArray(priorityCount);
                for (int i = 0; i < returnArray.Length; i++)
                {
                    returnArray[i] = tempArray[i];
                }
                return returnArray;
            }
      

  7.   

    参看了03年的一个帖子
    http://topic.csdn.net/t/20031118/15/2468022.html
    注意4楼的回复。主要还是依靠移位操作,和2楼的老兄思路基本一致的。下面作了一些修改,贴来分享一下public class UserRightConvert
    {
        public static bool[] GetBitArray(int exp)
        {
            int LongOne = 0x1, len = (int)Math.Ceiling(Math.Log(exp, 2));
            bool[] result = new bool[len];
            for (int i = 0; i < len; i++)
                result[len - i - 1] = (exp & (LongOne << i)) > 0;
            return result;
        }    public static int GetValue(bool[] items)
        {
            int result = 0, len = items.Length;
            for (int i = 0; i < len; i++)
                result = (result << 1) + (items[i] ? 1 : 0);
            return result;
        }
    }这个len = (int)Math.Ceiling(Math.Log(exp, 2))实在让我唏嘘,我想也解决了5楼的问题。
    7楼的问题我考虑作一个32长度的bool[],0位固定为true,只用后面31位该差不多够了。结贴
      

  8.   


            static void Main(string[] args)
            {
                bool[] boolArray = { true, false, true, false, false, true, true, true, false, false, false, false };
                Console.WriteLine(GetIntFromBoolArray(boolArray));
                foreach (bool b in GetBoolArrayFromInt(GetIntFromBoolArray(boolArray)))
                    Console.WriteLine(b);
            }        static int GetIntFromBoolArray(bool[] boolArray)
            {
                if (boolArray == null)
                    return -1;
                int length = boolArray.Length;
                int result = 0;
                for (int i = 0; i < length; i++)
                        result += boolArray[i] ? 1 << (length - 1 - i) : 0;
                return result;
            }        static bool[] GetBoolArrayFromInt(int num)
            {
                string str = Convert.ToString(num, 2);
                bool[] boolArray = new bool[str.Length];
                for (int i = 0; i < str.Length; i++)
                    boolArray[i] = str[i] == '1';
                return boolArray;
            }
    /*
    输出:
    2672
    True
    False
    True
    False
    False
    True
    True
    True
    False
    False
    False
    False
    */
      

  9.   

    int LongOne = 0x1, len = (int)Math.Ceiling(Math.Log(exp, 2)); 
    这句是不对的。
    如果bool[]前几位都是false,对应的int前几位都是0,len会少几位。