Why is the following code sample working?
Following is a code snippet that I tried to compile and run and it is working correctly.
-----------------------------------------------------------------------------------------------------------------------------------------
interface A {void myName();}
interface B {void myName();}class C : A, B
{
public void myName()
{
Console.WriteLine("I am myName ");
}
}
class Program
{
public static void Main()
{
C c = new C();
A a = new C();
B b = new C();
c. myName ();
a. myName ();
b. myName (); } }
Output
I am myName
I am myName
I am myName
-----------------------------------------------------------------------------------------------------------------------------------------
I cannot understand why it is working. There is only one function implemented in class C. My questions are:
1) When the lines c. myName (); a. myName (); b. myName (); are executed, how does the complier resolve the function calls?
2) Why the compiler does not give any error at the time of compilcation itself?
3) What feature of C# is behind the successful execution of above code?
4) Is this feature available in all versions of C# language released so far?
Please try to explain me in detail if possible.
Answers
The compiler only requires that you have the specific method required by the interface implemented at compile time. It checks the contract of A against C, then checks the contract of B against C. In both situations, you've implemented the method. Just because you only have to implement it once, doesn't mean it's not implemented for both interfaces. The compiler considers the single implementation for both interfaces to be sufficient for both interfaces.
1. It calls it the same way as it does the concrete class. With the callvirt IL instruction.
2. Because the method required for both interfaces is implemented. There's no need to implement it twice, because the signature is exactly the same for both interfaces.
3. Interface implementation.
4. Yes.By the way, you can use Explicit Interface Method Implementations (EIMI) to ensure you specify which interface you're implementing a particular method for. Doing this, you can actually create three methods that have the same signature, and can force a different reaction depending on what the type of the variable you're using is. Try changing C to the following:
class C : A, B
{
void A.myName()
{
Console.WriteLine("A");
}void B.myName()
{
Console.WriteLine("B");
}public void myName()
{
Console.WriteLine("C");
}
}
Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser- Proposed As Answer byVic Vega Wednesday, November 04, 2009 1:20 PM
- Marked As Answer byDavid M MortonMVP, ModeratorWednesday, November 04, 2009 2:44 PM
- Think about it this way:
There are two clubs you can belong to: chess club and glasses club.
Both clubs require you to wear glasses to join. If you don't wear glasses, you can't join either chess club or glasses club. The two clubs are completely unrelated from one another. Chess club doesn't even know about glasses club. You wear glasses, therefore, you are welcome to join both chess club and glasses club.
In other words, to answer 5, the compiler doesn't check the method and assign it to a specific interface. If it did that, how would it know which interface ot assign it to? Instead, it simply recognizes that the conditions to inherit from both interfaces are met in this one member.
6. I've already talked about the IL code. How much lower-level can I get? c.myName() and a.myName() both are called using callvirt. In other words, there are no differences.
7. The same as it was when I answered it the first time: "Yes".
Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser- Marked As Answer byDavid M MortonMVP, ModeratorWednesday, November 04, 2009 2:44 PM
I'll try to write it in C# terms to show you the general idea. Note that this is not at all compiler code, but it should give you an idea:
foreach (interface i on implementingClass)
foreach (member m on i)
if (!implementingClass.Implements(m))
throw new CompilerError("Not implemented");
The compiler doesn't make calls to myName. The JIT compiler makes those calls at runtime. The JIT compiler sees the callvirt IL instruction, the type (interface or class) and the method name implemented on the class. It then checks the actual type of the object, and moves from the bottom of the inheritance hierarchy (the class) to the top of the hierarchy (object) to see if there's a method that meets the necessary criteria needed to represent the called method. Next, if the method's instruction set hasn't already been committed to memory, the JIT compiler will read the instructions in the method implemented, and output the assembly instructions to memory, and a pointer to the start of these instructions is stored. If the method has already been emitted, the pointer is retrieved. Next, the JIT compiler will redirect the flow of the program to the location in memory specified by this pointer containing the method that was just JIT compiled, add the necessary parameters to the call stack, and call the method.
The class only needs to implement the common members once, but as I've shown above with the EIMI example, it can implement it separately for each interface. That's possible, but in most situations, it's best to implement the method only once to satisfy the conditions of both interfaces.
Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser- Marked As Answer byQuickLearner Wednesday, November 04, 2009 2:44 PM
All Replies
The compiler only requires that you have the specific method required by the interface implemented at compile time. It checks the contract of A against C, then checks the contract of B against C. In both situations, you've implemented the method. Just because you only have to implement it once, doesn't mean it's not implemented for both interfaces. The compiler considers the single implementation for both interfaces to be sufficient for both interfaces.
1. It calls it the same way as it does the concrete class. With the callvirt IL instruction.
2. Because the method required for both interfaces is implemented. There's no need to implement it twice, because the signature is exactly the same for both interfaces.
3. Interface implementation.
4. Yes.By the way, you can use Explicit Interface Method Implementations (EIMI) to ensure you specify which interface you're implementing a particular method for. Doing this, you can actually create three methods that have the same signature, and can force a different reaction depending on what the type of the variable you're using is. Try changing C to the following:
class C : A, B
{
void A.myName()
{
Console.WriteLine("A");
}void B.myName()
{
Console.WriteLine("B");
}public void myName()
{
Console.WriteLine("C");
}
}
Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser- Proposed As Answer byVic Vega Wednesday, November 04, 2009 1:20 PM
- Marked As Answer byDavid M MortonMVP, ModeratorWednesday, November 04, 2009 2:44 PM
Thanks David for a quick reply. I still have some more questions to ask in response to your reply.
When you say "It checks the contract of A against C, then checks the contract of B against C", do you mean that when compiler checks for the contract & if it finds any implementation for the same contract, it does not bind/mark the same implementation against the contract being checked ?
I mean if the complier checks for the implementation of the method defined in interface A & if it finds a method in class C corresponding to the method in interface A, it does not mark/bind that method as "This is a method implemented for, say method "X", in interface A.". (Question 5)
Also, what is the difference, at lower levels, between c. myName (); & a. myName (); method calls? (Question 6)
As per your reply above, I would say the answer to my third question is "When two interfaces define the same contract and if any class implements both the interfaces, the least that C# requires is that you should have a single generic(simply method name in the implementation without its interface's name as qualifier before the method name) implementation of the methods appearing in the contract."
Now if that is the answer to my third question, what would be the answer to the fourth one? (Question 7)
I tried my best to make my doubts very clear. Still if you don't get any point in my reply, feel free to ask me.
Thanks.- Think about it this way:
There are two clubs you can belong to: chess club and glasses club.
Both clubs require you to wear glasses to join. If you don't wear glasses, you can't join either chess club or glasses club. The two clubs are completely unrelated from one another. Chess club doesn't even know about glasses club. You wear glasses, therefore, you are welcome to join both chess club and glasses club.
In other words, to answer 5, the compiler doesn't check the method and assign it to a specific interface. If it did that, how would it know which interface ot assign it to? Instead, it simply recognizes that the conditions to inherit from both interfaces are met in this one member.
6. I've already talked about the IL code. How much lower-level can I get? c.myName() and a.myName() both are called using callvirt. In other words, there are no differences.
7. The same as it was when I answered it the first time: "Yes".
Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser- Marked As Answer byDavid M MortonMVP, ModeratorWednesday, November 04, 2009 2:44 PM
- David,
By "what is the difference, at lower levels, between c. myName (); & a. myName (); method calls?" question, I mean the steps that the compiler has to follow at the time of making calls to myName() method.
By "Instead, it simply recognizes that the conditions to inherit from both interfaces are met in this one member.", Do you mean that when a class implements two or more interfaces and if the method signatures for some of the methods defined in the interfaces are identical, the class may implement such methods only once?
Let me know. I'll try to write it in C# terms to show you the general idea. Note that this is not at all compiler code, but it should give you an idea:
foreach (interface i on implementingClass)
foreach (member m on i)
if (!implementingClass.Implements(m))
throw new CompilerError("Not implemented");
The compiler doesn't make calls to myName. The JIT compiler makes those calls at runtime. The JIT compiler sees the callvirt IL instruction, the type (interface or class) and the method name implemented on the class. It then checks the actual type of the object, and moves from the bottom of the inheritance hierarchy (the class) to the top of the hierarchy (object) to see if there's a method that meets the necessary criteria needed to represent the called method. Next, if the method's instruction set hasn't already been committed to memory, the JIT compiler will read the instructions in the method implemented, and output the assembly instructions to memory, and a pointer to the start of these instructions is stored. If the method has already been emitted, the pointer is retrieved. Next, the JIT compiler will redirect the flow of the program to the location in memory specified by this pointer containing the method that was just JIT compiled, add the necessary parameters to the call stack, and call the method.
The class only needs to implement the common members once, but as I've shown above with the EIMI example, it can implement it separately for each interface. That's possible, but in most situations, it's best to implement the method only once to satisfy the conditions of both interfaces.
Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser- Marked As Answer byQuickLearner Wednesday, November 04, 2009 2:44 PM
David,
My sincere thanks to you for making my doubts clear.
I really appreciate the effort that you put in to answer my questions.
Thanks indeed.


