Today, I discussed a question with my colleagues: Does an interface inherit from an object? All the books I have read about. Net tell me that "all the CTS-compliant types are inherited from system. Object", so interfaces also inherit from system. object. Code For example:
Class Program
{
Static Void Main ( String [] ARGs)
{
Iatm account = New Atmmachine ();
Account. getmoney ( 600 );
Console. writeline (account. tostring ());
Console. readkey ();
}
}
Public InterfaceIatm
{
VoidGetmoney (decimal amount );
}
Public ClassAtmmachine: iatm
{
PrivateDecimal B;
Public void getmoney (decimal amount)
{< br> B += amount;
}
Public Override StringTostring ()
{
ReturnString. Format ("Getted money = {0, 6: c}", B );
}
}
Compile the code and decompile it with IL dasm to view the iatm de il code, as shown below:
. Class interface public abstract auto ANSI leleapplication2.iatm
{
} // End of class consoleapplication2.iatm Compared with other types, for example:
. Class private auto ANSI beforefieldinit leleapplication2.program
Extends [mscorlib] system. Object
{
} // End of class consoleapplication2.program All have. the class identifier indicates that the interface is actually a class, but it is a special class. It also describes a problem. The iatm interface does not inherit the system. object, otherwise there should be extends [mscorlib] system. object. So what exactly does the interface inherit? Using Al dasm to view metadata files (CTRL + M), there are the following fragments: 02000003 mark interface: iatm, 02000004 mark Class: atmmachine
Typedef #2 (02000003)
-------------------------------------------------------
Typdefname: leleapplication2.iatm (02000003)
Flags: [public] [autolayout] [interface] [Abstract] [ansiclass] (000000a1)
Extends: 01000000 [typeref]
Method #1 (06000003)
-------------------------------------------------------
Methodname: getcurrency (06000003)
Flags: [public] [Virtual] [hidebysig] [newslot] [Abstract] (000005c6)
RVA: 0x00000000
Implflags: [il] [managed] (00000000)
Callcnvntn: [Default]
Hasthis
Returntype: void
1 arguments
Argument #1: valueclass system. Decimal
1 Parameters
(1) paramtoken: (08000002) Name: Amount flags: [none] (00000000)
Typedef #3 (02000004)
-------------------------------------------------------
Typdefname: leleapplication2.atmmachine (02000004)
Flags: [public] [autolayout] [Class] [ansiclass] [beforefieldinit] (00100001)
Extends: 01000001 [typeref] system. Object
Field #1 (04000001)
-------------------------------------------------------
Field name: B (04000001)
Flags: [private] (00000001)
Callcnvntn: [field]
Field Type: valueclass system. Decimal
Method #1 (06000004)
-------------------------------------------------------
Methodname: getcurrency (06000004)
Flags: [public] [Final] [Virtual] [hidebysig] [newslot] (000001e6)
RVA: 0x0000208f
Implflags: [il] [managed] (00000000)
Callcnvntn: [Default]
Hasthis
Returntype: void
1 arguments
Argument #1: valueclass system. Decimal
1 Parameters
(1) paramtoken: (08000003) Name: Amount flags: [none] (00000000) Pay attention to the extends identifier, which indicates the type inherited by the current type. here we can see that iatm does not inherit system. object, otherwise there should be extends: 01000001 [typeref] system. the description of object. What is 01000000 [typeref? I understand that nothing is inherited. Opening mscorlib. dll has the following metadata description fragments:
Typedef #1 (02000002)
-------------------------------------------------------
Typdefname: system. Object (02000002)
Flags: [public] [autolayout] [Class] [serializable] [ansiclass] [beforefieldinit] (00102001)
Extends: 01000000 [typeref]
Method #1 (06000001)
-------------------------------------------------------
Methodname:. ctor (06000001)
Flags: [public] [hidebysig] [reuseslot] [specialname] [rtspecialname] [. ctor] (00001886)
RVA: 0x000020d0
Implflags: [il] [managed] (00000000)
Callcnvntn: [Default]
Hasthis
Returntype: void
No arguments.
Customattribute #1 (0c000001)
-------------------------------------------------------
Customattribute type: 06003055
Customattributename: system. runtime. constrainedexecution. Conflict: instance void. ctor (value class system. runtime. constrainedexecution. Consistency, value class system. runtime. constrainedexecution. CER)
Length: 12
Value: 01 00 03 00 00 00 01 00 00 00 00> <
Ctor ARGs: (<can not decode>) The content after the extends identifier is also 01000000 [typeref],
Therefore, neither interface nor system. object inherits any type. In fact, here 01000000 (0x01000000) is the metadata identifier (metadata token), which is a 4-byte value, and the highest bit is used to identify the current metadata type, for example: 01 indicates that the metadata is a typeref, 02 indicates typedef, 04 indicates fielddef, 06 indicates methoddef, and 08 indicates paramdef. for a minimum of three places, in short, it can be seen that the current metadata is indexed in the metadata table (the storage of the metadata table is complex). For example, 0x0400001b indicates that the metadata is a field, the index position in the metadata table is 27th rows. As you can see from 0x0000000, it indicates that the type of the current metadata identity is a typeref and Its Index position in the metadata table is 0, in fact, no data is stored at the index position 0 of the metadata table, so such an identifier is called the "nil" identifier. Last question: iatm account = new atmmachine (); Iatm account; (of course, this write will not pass the compilation, but smart sensing is still valid) account. getmoney (600); or Account. getmoney (600); enter the account in the IDE. in addition to the getmoney method defined in iatm, there are four methods: tostring, GetType, equals, and gethashcode. Now we use the iatm interface to access the object, iatm does not have the extends system. object, so smart sensing should only use the getmoney method, but this is not the case. Why? I have not found the answer from the metadata. I hope you can give me some advice.
In addition, I make the following guesses: Only class or struct can be accessed through the interface, and as long as it is the type in the managed code, both Class and struct inherit from system. object (struct inherits from system. valuetype, while system. valuetype inherits from system. object), so the above four methods are always made public, so account. five methods instead of one.
Finally, you can remove extends: 01000000 by modifying metadata .... then compile the new DLL and the DLL is available. I think the code at this time is no longer managed code and does not comply with the CLS specification, therefore, not all types are inherited from system. the object may not be suitable.