MSDN中解释bool与Boolean的关系是:“bool 关键字是 System.Boolean 的别名”。观察上面的Boolean类型定义,在其继承的泛型接口和成员变量中,我们找到了“bool”的影子(我想可能时Reflector将IL代码反汇编时将类型Boolean翻译成C#中的关键字bool),也就是说Boolean的定义依赖与bool(Boolean)。这就好比鸡蛋与鸡,到底是先有鸡蛋还是先有鸡?到底是先有Boolean的类型定义还是先有Boolean类型呢?
C/C++中没有提供bool类型,我们可以用0和非0取而代之;而在.Net中则提供了一个Boolean类型,其实是对0/1的一个封装。下面我们来看下这段代码:
Boolean b= true;
Console.WriteLine(sizeof(Boolean));//得到的结果是1byte
unsafe//先要用/unsafe(项目属性->Build->Allow unsafe code)来关闭安全检查
...{
int i = (int)&b;//取地址
Console.WriteLine(*(byte*)i);//上面得到bool类型占1byte,这里将Boolean中的值按byte来读取
}
Console.WriteLine(sizeof(Boolean));//得到的结果是1byte
unsafe//先要用/unsafe(项目属性->Build->Allow unsafe code)来关闭安全检查
...{
int i = (int)&b;//取地址
Console.WriteLine(*(byte*)i);//上面得到bool类型占1byte,这里将Boolean中的值按byte来读取
}
得出的结果是1,当Boolean变量b赋值为false时,得到的结果是0。虽然只用1个bit就可以表示0/1了,但计算机存储的最小单位是byte,没办法只好浪费另外7个bit了:)
现在转入正题来扯淡,出于对Boolean的好奇,我用Reflector反汇编了下mscorlib.dll,得到Boolean的源代码(完整的代码见附录),居然看到了下面的内容:
public struct Boolean : IComparable, IConvertible, IComparable<bool>, IEquatable<bool>
...{
private bool m_value;
//省略其他成员的定义.....
}
...{
private bool m_value;
//省略其他成员的定义.....
}
MSDN中解释bool与Boolean的关系是:“bool 关键字是 System.Boolean 的别名”。观察上面的Boolean类型定义,在其继承的泛型接口和成员变量中,我们找到了“bool”的影子(我想可能时Reflector将IL代码反汇编时将类型Boolean翻译成C#中的关键字bool),也就是说Boolean的定义依赖与bool(Boolean)。这就好比鸡蛋与鸡,到底是先有鸡蛋还是先有鸡?到底是先有Boolean的类型定义还是先有Boolean类型呢?
附录 - Boolean类源码:
1namespace System
2{
3 using System.Globalization;
4 using System.Runtime.InteropServices;
5
6 [Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true)]
7 public struct Boolean : IComparable, IConvertible, IComparable<bool>, IEquatable<bool>
8 {
9 internal const int True = 1;
10 internal const int False = 0;
11 internal const string TrueLiteral = "True";
12 internal const string FalseLiteral = "False";
13 private bool m_value;
14 private static char[] m_trimmableChars;
15 public static readonly string TrueString;
16 public static readonly string FalseString;
17 public override int GetHashCode()
18 {
19 if (!this)
20 {
21 return 0;
22 }
23 return 1;
24 }
25
26 public override string ToString()
27 {
28 if (!this)
29 {
30 return "False";
31 }
32 return "True";
33 }
34
35 public string ToString(IFormatProvider provider)
36 {
37 if (!this)
38 {
39 return "False";
40 }
41 return "True";
42 }
43
44 public override bool Equals(object obj)
45 {
46 if (obj is bool)
47 {
48 return (this == ((bool) obj));
49 }
50 return false;
51 }
52
53 public bool Equals(bool obj)
54 {
55 return (this == obj);
56 }
57
58 public int CompareTo(object obj)
59 {
60 if (obj != null)
61 {
62 if (!(obj is bool))
63 {
64 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeBoolean"));
65 }
66 if (this == ((bool) obj))
67 {
68 return 0;
69 }
70 if (!this)
71 {
72 return -1;
73 }
74 }
75 return 1;
76 }
77
78 public int CompareTo(bool value)
79 {
80 if (this == value)
81 {
82 return 0;
83 }
84 if (!this)
85 {
86 return -1;
87 }
88 return 1;
89 }
90
91 public static bool Parse(string value)
92 {
93 if (value == null)
94 {
95 throw new ArgumentNullException("value");
96 }
97 bool result = false;
98 if (!TryParse(value, out result))
99 {
100 throw new FormatException(Environment.GetResourceString("Format_BadBoolean"));
101 }
102 return result;
103 }
104
105 public static bool TryParse(string value, out bool result)
106 {
107 result = false;
108 if (value != null)
109 {
110 if ("True".Equals(value, StringComparison.OrdinalIgnoreCase))
111 {
112 result = true;
113 return true;
114 }
115 if ("False".Equals(value, StringComparison.OrdinalIgnoreCase))
116 {
117 result = false;
118 return true;
119 }
120 if (m_trimmableChars == null)
121 {
122 char[] destinationArray = new char[string.WhitespaceChars.Length + 1];
123 Array.Copy(string.WhitespaceChars, destinationArray, string.WhitespaceChars.Length);
124 destinationArray[destinationArray.Length - 1] = '\0';
125 m_trimmableChars = destinationArray;
126 }
127 value = value.Trim(m_trimmableChars);
128 if ("True".Equals(value, StringComparison.OrdinalIgnoreCase))
129 {
130 result = true;
131 return true;
132 }
133 if ("False".Equals(value, StringComparison.OrdinalIgnoreCase))
134 {
135 result = false;
136 return true;
137 }
138 }
139 return false;
140 }
141
142 public TypeCode GetTypeCode()
143 {
144 return TypeCode.Boolean;
145 }
146
147 bool IConvertible.ToBoolean(IFormatProvider provider)
148 {
149 return this;
150 }
151
152 char IConvertible.ToChar(IFormatProvider provider)
153 {
154 throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_FromTo"), new object[] { "Boolean", "Char" }));
155 }
156
157 sbyte IConvertible.ToSByte(IFormatProvider provider)
158 {
159 return Convert.ToSByte(this);
160 }
161
162 byte IConvertible.ToByte(IFormatProvider provider)
163 {
164 return Convert.ToByte(this);
165 }
166
167 short IConvertible.ToInt16(IFormatProvider provider)
168 {
169 return Convert.ToInt16(this);
170 }
171
172 ushort IConvertible.ToUInt16(IFormatProvider provider)
173 {
174 return Convert.ToUInt16(this);
175 }
176
177 int IConvertible.ToInt32(IFormatProvider provider)
178 {
179 return Convert.ToInt32(this);
180 }
181
182 uint IConvertible.ToUInt32(IFormatProvider provider)
183 {
184 return Convert.ToUInt32(this);
185 }
186
187 long IConvertible.ToInt64(IFormatProvider provider)
188 {
189 return Convert.ToInt64(this);
190 }
191
192 ulong IConvertible.ToUInt64(IFormatProvider provider)
193 {
194 return Convert.ToUInt64(this);
195 }
196
197 float IConvertible.ToSingle(IFormatProvider provider)
198 {
199 return Convert.ToSingle(this);
200 }
201
202 double IConvertible.ToDouble(IFormatProvider provider)
203 {
204 return Convert.ToDouble(this);
205 }
206
207 decimal IConvertible.ToDecimal(IFormatProvider provider)
208 {
209 return Convert.ToDecimal(this);
210 }
211
212 DateTime IConvertible.ToDateTime(IFormatProvider provider)
213 {
214 throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_FromTo"), new object[] { "Boolean", "DateTime" }));
215 }
216
217 object IConvertible.ToType(Type type, IFormatProvider provider)
218 {
219 return Convert.DefaultToType(this, type, provider);
220 }
221
222 static Boolean()
223 {
224 TrueString = "True";
225 FalseString = "False";
226 }
227 }
228}