内存分配接口

时间:2012-12-03 19:33:13

标签: c# memory-management

我知道接口无法实例化,但是如果我们将它分配给一个对象,那么有人可以解释如何将内存分配给它。例如:

ITest obj = (ITest) new TestClass1();  //TestClass1 is a class which implements ITest
obj.MethodsDefinedInInterface();

ITest是否转换为object以保存TestClass1的属性和方法。

8 个答案:

答案 0 :(得分:4)

我不确定'分配'究竟是什么意思。以下语句分为两个单独的“分配”:

TestClass1 test = new TestClass1();

首先是new TestClass1()语句,它在堆上分配sizeof(TestClass1)。其次,堆分配地址的赋值存储在变量test中,该变量在堆栈上分配为sizeof(object *)(即IntPtr.Size,或基于硬件+的32/64位) OS +软件运行)。

以下声明在“分配”中完全相同:

ITest test = new TestClass1();

两者之间的唯一区别是可以在变量test上调用的方法。

注意:对于实现接口的结构,情况并非如此。接口必须是一个引用类型,如您所知,结构不是。这在.NET中称为 boxing ,允许通过首先在堆上放置结构的副本来引用结构,就好像它是引用类型一样。

所以我们现在重新评估声明:

TestSTRUCT1 test2 = new TestSTRUCT1();

这在命名变量test2的堆栈上'分配'sizeof(TestSTRUCT1)。 (不确定赋值给new TestSTRUCT1()的影响是什么,它可能会创建一个额外的堆栈副本,但应该在赋值后立即删除。

如果我们然后将此值分配给接口:

ITest test3 = test2;

我们现在又进行了两次分配。首先将结构复制到堆中。然后,该堆驻留结构的地址被放置在一个新的“已分配”变量test3中(在堆栈上)。

答案 1 :(得分:2)

它应该类似于:

TestClass1 test = new TestClass1();  
ITest obj = (ITest) test;
obj.MethodsDefinedInInterface();

我认为,这回答了你的问题。

答案 2 :(得分:1)

为实现接口的对象分配内存,就像任何其他对象一样。它是否实现接口只是对象的属性

答案 3 :(得分:1)

仅为TestClass1实例分配内存。接口ITest只是一种引用类型,它指向已分配的内存。

答案 4 :(得分:1)

  

ITest是否转换为对象以保存TestClass1的属性和方法

ITest是一种类型。 TestClass1属性和方法仍然存在,只是你无法通过obj变量访问它。

答案 5 :(得分:1)

它非常简单。您为TestClass1分配,然后将其强制转换回接口。请注意,您没有实例化接口,您实例化了一个实现接口的类,然后调用在具体类中实现的(必须的)接口方法!

另一种表达方式是:

TestClass1 test = new TestClass1();
ITest obj = (ITest) test;
obj.MethodsDefinedInInterface();

请注意,分配的区域适用于TestClass1!它不会因为演员而成长或缩小!

答案 6 :(得分:1)

interfaces只需在编译时确保对象在技术和逻辑上符合cerain标准。

执行代码并使用接口时,将分配内存,就好像您只是使用类实例化对象一样。

所以

之间没有区别(就内存分配而言)
ITest obj = (ITest) new TestClass1();  //TestClass1 is a class which implements ITest
obj.MethodsDefinedInInterface();

TestClass1 obj = new TestClass1();  //TestClass1 is a class which implements ITest
obj.MethodsDefinedInInterface();

答案 7 :(得分:1)

因此,首先,当您输入此方法时,将在堆栈上为所有参数(如果适用)分配空间,返回值(如果适用)以及该方法的所有局部变量。对于我们在此处显示的内容,唯一需要分配的局部变量是objobj是一个接口,因此需要足够的空间用于单个引用(3​​2位系统为32位,64位系统为64位)。由于没有其他局部变量,返回值或参数,我们只会占用堆栈中的那一个字。

因为我们正在分配单个对象(new TestClass1())并假设该对象是一个类(而不是struct,因为命名struct TestClass1将是非常卑鄙的)将在堆上分配足够的空间来考虑TestClass的单个实例。对于每个单独的字段(无论可访问性),该空间都将有足够的空间加上一些额外的对象开销。对这个新分配的对象的引用将进入为我们的局部变量分配的堆栈中的位置。

这都忽略了处理器在运行时使用的寄存器;由于编译器,抖动,操作系统,处理器硬件等的复杂转换和优化,我无法开始尝试预测会采取什么措施。幸运的是,由于所有这些抽象,我真的不需要关心。