假如有一个
struct Piont
{
Int32 x;
Int32 y;
}struct是值类型,所以没有无参构造函数,但是却可以Point p = new Point();这样做算不算调用构造函数,如果是的话,这部分内存是在堆上分配的还是在栈上分配,按理说应该在堆上分配吧!Point p = new Point();
p.x=1;
p.y = 1;Piont p1,
p1.x=1;
p1.y=1;这样p.Equal(p1)是true这点我觉得应该是System.ValueType重写了equals方法的缘故吧!主要是对Point p = new Point();这个new方法的使用,以及分配内存的位置有点不解,求高手解答!
这部分内存是在堆上分配的还是在栈上分配 - 栈上
p.Equal(p1)是true这点我觉得应该是System.ValueType重写了equals方法 - 对
struct(结构)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体 。所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈(stack)上,它本身存储了值,而不包含指向该值的指针。所以在使用struct时,我们可以将其当作int、char这样的基本类型类对待。
这么说只要valuetype分配内存一定是在栈上,而与new无关了,new关心的只是分配内存而不关心在哪分配内存?
In the Point value type defined earlier, no default parameterless constructor is defined
也就是说它没有默认的无参构造了,既然如此怎么能Point p = new Point();这么使用,我最疑惑的是这个!
{
// Methods
protected ValueType()
{
} public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
RuntimeType rt = (RuntimeType) base.GetType();
RuntimeType type = (RuntimeType) obj.GetType();
if (type != rt)
{
return false;
}
object obj2 = this;
FieldInfo[] infoArray = RuntimeType.InternalGetFields(rt, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, false);
for (int i = 0; i < infoArray.Length; i++)
{
object obj3 = RuntimeFieldInfo.InternalGetValue((RuntimeFieldInfo) infoArray[i], obj2, false);
object obj4 = RuntimeFieldInfo.InternalGetValue((RuntimeFieldInfo) infoArray[i], obj, false);
if (obj3 == null)
{
if (obj4 != null)
{
return false;
}
}
else if (!obj3.Equals(obj4))
{
return false;
}
}
return true;
} public override int GetHashCode()
{
RuntimeType rt = (RuntimeType) base.GetType();
FieldInfo[] infoArray = RuntimeType.InternalGetFields(rt, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, false);
if (infoArray.Length > 0)
{
for (int i = 0; i < infoArray.Length; i++)
{
object obj2 = RuntimeFieldInfo.InternalGetValue((RuntimeFieldInfo) infoArray[i], this, false);
if (obj2 != null)
{
return obj2.GetHashCode();
}
}
}
return rt.GetHashCode();
}
}
你看的是ValueType的源码么?
当值类型有构造函数时,使用的是call,调用的是含参的构造函数而对于引用类型,他始终调用的是newobj命令默认值类型new确实是没有产生构造函数,因为用的是initobj 命令。还纠结啥?
我想再问个问题,既然它有默认构造,为什么不像class那样,再中间语言里边可以看得到呢?
{
MyPoint o = new MyPoint();
MyPoint2 o2 = new MyPoint2();
Console.ReadKey();
} public struct MyPoint
{
public int x;
public int y;
} public class MyPoint2
{
public int x;
public int y;
} MyPoint o = new MyPoint();
00000035 lea edi,[ebp-44h]
00000038 pxor xmm0,xmm0
0000003c movq mmword ptr [edi],xmm0
MyPoint2 o2 = new MyPoint2();
00000040 mov ecx,569F08h
00000045 call FFD40AD4
0000004a mov dword ptr [ebp-4Ch],eax
0000004d mov ecx,dword ptr [ebp-4Ch]
00000050 call FFD5B068
00000055 mov eax,dword ptr [ebp-4Ch]
00000058 mov dword ptr [ebp-48h],eax
{
public int x;
public test2(int x)
{
this.x = x;
}
}
test2 a = new test2();
test2 b;
b.x = 0;
test2 c = new test2(0);
IL_0000: nop
IL_0001: ldloca.s a
IL_0003: initobj WindowsFormsApplication1.test2
IL_0009: ldloca.s b
IL_000b: ldc.i4.0
IL_000c: stfld int32 WindowsFormsApplication1.test2::x
IL_0011: ldloca.s c
IL_0013: ldc.i4.0
IL_0014: call instance void WindowsFormsApplication1.test2::.ctor(int32)
IL_0019: nop
IL_001a: ret