- Types
- Control Structures
- Object Members
- Events and Delegates
- Object Semantics
- Summary
Object Semantics
One of the primary concepts of C# is that, in many places, it forces a programmer to explicitly specify his intent. This eliminates a class of errors associated with assumption of default behavior in languages such as Java. For example, for polymorphism to occur in C#, a normal base class must declare a method as virtual, and the derived class must declare the overriding method with the overrides keyword. Without this explicit declaration, all calls to a base class reference execute a base class method, even if the actual object type is a derived class. Here's a C# method declaration:
class Bar { public Bar() { MyMethod(); } public void MyMethod() { Console.WriteLine("Bar.MyMethod()"); } } class Foo : Bar { static void Main(string[] args) { Bar myFoo = new Foo(); } public void MyMethod() { Console.WriteLine("Foo.MyMethod()"); } }
This produces "Bar.MyMethod()". This shows how C# produces a well-versioned implementation. Now here's the Java implementation:
class Bar { public Bar() { MyMethod(); } public void MyMethod() { System.out.println("Bar.MyMethod()"); } } public class Foo extends Bar { public static void main(String[] args) { Bar myFoo = new Foo(); } public void MyMethod() { System.out.println("Foo.MyMethod()"); } }
This produces "Foo.MyMethod()". It also reveals potentially serious versioning problems. Say that class Bar belongs to a third-party library, which doesn't implement MyMethod() in version 1.0, and the only MyMethod() called is to an instance of class Foo. The problem occurs when the third-party library updates class Bar to version 2.0 and adds MyMethod(). Because of implicit polymorphism, any call in class Bar to MyMethod() will accidentally invoke Foo.MyMethod().