简体   繁体   English

内存分配接口

[英]Memory allocation of interface

I know interface cannot be instantiated, but if we assign it to an object, could anyone please explain how the memory gets allocated to it. 我知道接口无法实例化,但如果我们将它分配给一个对象,任何人都可以解释如何将内存分配给它。 For ex: 例如:

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

Does ITest converts to object to save properties and methods of TestClass1. ITest是否转换为对象以保存TestClass1的属性和方法。

I'm not sure exactly what you mean by 'allocation'. 我不确定'分配'究竟是什么意思。 The following statement makes two seperate 'allocations': 以下语句分为两个单独的“分配”:

TestClass1 test = new TestClass1();

First is the new TestClass1() statement which allocates sizeof(TestClass1) on the heap. 首先是new TestClass1()语句,它在堆上分配sizeof(TestClass1)。 Second, the assignment of the address of the heap allocation is stored in the variable test , which is allocated on the stack as sizeof(object *) (ie IntPtr.Size, or 32/64 bits based on the hardware+OS+software running). 其次,堆分配地址的赋值存储在变量test ,该变量在堆栈上分配为sizeof(object *)(即IntPtr.Size,或基于硬件+ OS +软件运行的32/64位) )。

The following statement is EXACTLY the same in 'allocations': 以下声明在“分配”中完全相同:

ITest test = new TestClass1();

The only difference between the two is the methods available to be called on the variable test . 两者之间的唯一区别是可以在变量test调用的方法。

Note: This is NOT true with a structure that implements an interface. 注意:对于实现接口的结构,情况并非如此。 Interfaces must be a reference type, and as you know, structs are not. 接口必须是引用类型,如您所知,结构不是。 This is called boxing in .NET and allows a struct to be referenced as if it were a reference type by first placing a copy of the struct on the heap. 这在.NET中称为装箱 ,并允许通过首先在堆上放置结构的副本来引用结构,就好像它是引用类型一样。

So we now re-evaluate the statement: 所以我们现在重新评估声明:

TestSTRUCT1 test2 = new TestSTRUCT1();

This 'allocates' sizeof(TestSTRUCT1) on the stack at the named variable test2 . 这在命名变量test2的堆栈上“分配”sizeof(TestSTRUCT1)。 (Not sure what the impact of the assignment to new TestSTRUCT1() is, it may create an additional stack copy but that should be removed immediately after the assignment. (不确定赋值给new TestSTRUCT1()是什么,它可能会创建一个额外的堆栈副本,但应该在赋值后立即删除。

If we then assign this value to an interface: 如果我们然后将此值分配给接口:

ITest test3 = test2;

We have now made two more allocations. 我们现在又做了两次分配。 First the structure is copied to the heap. 首先将结构复制到堆中。 Then the address of that heap-resident structure is placed in a newly 'allocated' variable test3 (on the stack). 然后,该堆驻留结构的地址被放置在新的“已分配”变量test3 (在堆栈上)。

It should be similar to: 它应该类似于:

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

Which, I think, answers your question. 我认为,这回答了你的问题。

Memory gets allocated for the object that impliments interface like any other object. 内存被分配给与任何其他对象一样实现接口的对象。 whether or not it impliments an interface is just a property of the object 它是否暗示接口只是对象的属性

Memory is allocated only for TestClass1 instance. 内存仅分配给TestClass1实例。 Interface ITest is only a type of reference, which points to that allocated memory. 接口ITest只是一种引用,它指向分配的内存。

Does ITest converts to object to save properties and methods of TestClass1 ITest是否转换为对象以保存TestClass1的属性和方法

ITest is a type. ITest是一种类型。 TestClass1 properties and methods are still there just you cannot access it via obj variable. TestClass1属性和方法仍然存在,只是你无法通过obj变量访问它。

Its quite simple acutally. 它非常简单。 You allocate for TestClass1 and then cast it back to the interface. 您为TestClass1分配,然后将其强制转换回接口。 Note that you're not instantiating a interface, you're instantiating a class that implements the interface and then calling the interface method which is implemented (obligatorily) in the concrete class! 请注意,您没有实例化一个接口,您实例化一个实现该接口的类,然后调用在具体类中实现(必须)的接口方法!

another way to put it is: 另一种说法是:

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

note that the allocated area is for TestClass1! 请注意,分配的区域是TestClass1! it not grow or shrink because of the cast! 它不会因为演员而成长或缩小!

interfaces simply make sure that objects meet a cerain criteria both tecnically and logically at compile time. interfaces只需确保对象在编译时在tecnically和逻辑上满足cerain标准。

When executing the code and using an interface memory will be allocated as if you would just instantiate the object using the class. 执行代码并使用接口时,将分配内存,就好像您只是使用类实例化对象一样。

So there's no difference (in terms of memory allocaton) between 所以两者之间没有区别(就内存分配而言)

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

and

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

So, first, when you enter this method space will be allocated on the stack for all parameters, if applicable, the return value, if applicable, and all local variables for that method. 因此,首先,当您输入此方法时,将在堆栈上为所有参数(如果适用)分配空间,返回值(如果适用)以及该方法的所有局部变量。 For what we've shown here the only local variable that needs to be allocated is obj . 对于我们在这里展示的内容,唯一需要分配的局部变量是obj obj is an interface, and so requires enough space for a single reference (32 bits on 32 bit systems, 64 bits on 64 bit systems). obj是一个接口,因此需要足够的空间用于单个引用(3​​2位系统为32位,64位系统为64位)。 Since there are no other local variables, return values, or parameters, we will only take up that one word on the stack. 由于没有其他局部变量,返回值或参数,我们只会占用堆栈中的那个字。

Because we're allocating a single object ( new TestClass1() ) and assuming that object is a class (and not a struct , because naming a struct TestClass1 would be very mean) enough space will be allocated on the heap to account for a single instance of TestClass . 因为我们正在分配单个对象( new TestClass1() )并假设该对象是一个类(而不是struct ,因为命名struct TestClass1将非常TestClass1 )将在堆上分配足够的空间来解释单个对象TestClass实例。 That space will be enough space for every single field (regardless of accessibility) plus a little extra for some object overhead. 对于每个单独的字段(无论可访问性),该空间都将有足够的空间加上一些额外的对象开销。 A reference to this newly allocated object will go in the spot on the stack that is allocated for our local variable. 对这个新分配的对象的引用将进入为我们的局部变量分配的堆栈上的位置。

This is all ignoring the registers utilized by the processor at runtime; 这都忽略了处理器在运行时使用的寄存器; due to the complex transformations and optimizations of compilers, jitters, operating systems, processor hardware, etc. I couldn't begin to try to predict what that would take. 由于编译器,抖动,操作系统,处理器硬件等的复杂转换和优化,我无法开始尝试预测会采取什么措施。 Fortunately, thanks to all of those abstractions, I don't really need to care. 幸运的是,由于所有这些抽象,我真的不需要关心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM