publicstructMyStruct0{publicstring Name { get; set; } // Call ToString() will call ValueType.ToString(), which has boxing}publicstructMyStruct1{publicstring Name { get; set; }publicoverridestringToString() {return base.ToString(); // boxing }}publicstructMyStruct2{publicstring Name;publicoverridestringToString() {return Name; // no boxing }}MyStruct0 m0 =newMyStruct0();MyStruct1 m1 =newMyStruct1();MyStruct2 m2 =newMyStruct2();m0.ToString(); // boxingm1.ToString(); // boxingm2.ToString(); // no boxing, see ToString() defined in MyStruct2
// System.ValueType/// <summary>Indicates whether this instance and a specified object are equal.</summary>/// <param name="obj">The object to compare with the current instance. </param>/// <returns>/// <see langword="true" /> if <paramref name="obj" /> and this instance are the same type and represent the same value; otherwise, <see langword="false" />. </returns>
// Token: 0x06001570 RID: 5488 RVA: 0x0003EC40 File Offset: 0x0003CE40[SecuritySafeCritical][__DynamicallyInvokable]publicoverrideboolEquals(object obj){if (obj ==null) {returnfalse; }RuntimeType runtimeType = (RuntimeType)base.GetType();RuntimeType left = (RuntimeType)obj.GetType();if (left != runtimeType) {returnfalse; }if (ValueType.CanCompareBits(this)) {returnValueType.FastEqualsCheck(this, obj); }FieldInfo[] fields =runtimeType.GetFields(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);for (int i =0; i <fields.Length; i++) {object obj2 = ((RtFieldInfo)fields[i]).UnsafeGetValue(this);object obj3 = ((RtFieldInfo)fields[i]).UnsafeGetValue(obj);if (obj2 ==null) {if (obj3 !=null) {returnfalse; } }elseif (!obj2.Equals(obj3)) {returnfalse; } }returntrue;}
灵魂拷问结束。
如果对.NET CLR没有系统性的了解,看到这些问题可能已经满头大汗。推荐看《CLR via C#》第二部分(尤其第5章),相信阅读后会豁然开朗。