unimportant logo identifying Barry Cornelius

University of Oxford

Computing Services

Comparing .NET with Java

  Author: Barry Cornelius Date: 29th October 2002; first created: 12th January 2002

Contents

1. Introduction

Primary Aim:

Secondary Aims:

2. The .NET Framework

2.1. Overview of the .NET Framework

2.2. The Common Language Runtime

A .NET compiler writer can rely on the CLR:

2.3. The Common Type System

2.4. The primitive types

There is a set of primitive types some of which must be provided. They are:

size C# Visual Basic.NET
System.Boolean 8 bool Boolean
System.Byte 8 byte Byte
System.Int16 16 short Short
System.Int32 32 int Integer
System.Int64 64 long Long
System.Float 32 float Single
System.Double 64 double Double
System.Char 16 char Char
System.Decimal 128 decimal Decimal

2.5. Language interoperability

2.6. Tool support

2.7. Deployment

2.8. Versioning

3. Moving to the .NET Framework

3.1. Introducing C# and Visual Basic.NET

3.2. Similarities with Java

namespace First
{
    public class Point
    {
        private int iX;
        private int iY;
        public Point(int pX, int pY)
        {
            iX = pX;
            iY = pY;
        }
        public override string ToString()
        {
            return iX + ":" + iY;
        }
    }
}
using System;
namespace First
{
    public class PointTest
    {
        public static void Main()
        {
            Point tPoint = new Point(100, 200);
            Console.WriteLine(tPoint);
            Point tAnotherPoint = tPoint;
            Console.WriteLine(tAnotherPoint);
        }
    }
}
namespace First
{
    public class NamedPoint : Point
    {
        private string iName;
        public NamedPoint(string pName, int pX, int pY)
            : base(pX, pY)
        {
            iName = pName;
        }
        public override string ToString()
        {
            return iName + "%" + base.ToString();
        }
    }
}
using System;
namespace First
{
    public class NamedPointTest
    {
        public static void Main()
        {
            NamedPoint tNamedPoint = new NamedPoint("first", 100, 200);
            Console.WriteLine(tNamedPoint);
            Point tPoint = tNamedPoint;
            Console.WriteLine(tPoint);
        }
    }
}
Public Class Point
    Private iX As Integer
    Private iY As Integer
    Public Sub New(ByVal pX As Integer, ByVal pY As Integer)
        iX = pX
        iY = pY
    End Sub
    Public Overrides Function ToString() As String
        Return iX & ":" & iY
    End Function
End Class
Module PointTest
    Sub Main()
        Dim tPoint As Point = New Point(100, 200)
        Console.WriteLine(tPoint)
        Dim tAnotherPoint As Point = tPoint
        Console.WriteLine(tAnotherPoint)
    End Sub
End Module
Public Class NamedPoint
    Inherits Point
    Private iName As String
    Public Sub New(ByVal pName As String, ByVal pX As Integer, ByVal pY As Integer)
        MyBase.New(pX, pY)
        iName = pName
    End Sub
    Public Overrides Function ToString() As String
        Return iName & "%" & MyBase.ToString()
    End Function
End Class
Module NamedPointTest
    Sub Main()
        Dim tNamedPoint As NamedPoint = New NamedPoint("first", 100, 200)
        Console.WriteLine(tNamedPoint)
        Dim tPoint As Point = tNamedPoint
        Console.WriteLine(tPoint)
    End Sub
End Module

We have now provided 4 classes in both C# and VB.NET:

We can mix the languages, e.g., use C#'s NamedPointTest class with VB.NET's NamedPoint class and C#'s Point class.

3.3. Differences from Java

We now look at some of the ways in which C# and Visual Basic.NET are different from Java.

Here is an example of a struct type coded in C#:

namespace First
{
    public struct SPoint
    {
        private int iX;
        private int iY;
        public SPoint(int pX, int pY)
        {
            iX = pX;
            iY = pY;
        }
        public override string ToString()
        {
            return iX + ":" + iY;
        }
    }
}

Here is a method that uses this struct type:

using System;
namespace First
{
    public class SPointTest
    {
        public static void Main()
        {
            SPoint tSPoint = new SPoint(100, 200);
            Console.WriteLine(tSPoint);
            SPoint tAnotherSPoint = tSPoint;
            Console.WriteLine(tAnotherSPoint);
        }
    }
}

3.3.1. Types

  • You cannot extend struct types (e.g., to produce NamedSPoint).
  • Each primitive type is just an alias for a struct type.
  • So int in C# and Integer in VB.NET are aliases for the struct type System.Int32.
  • Both C# and VB.NET have enumeration types.
  • Here is an example coded in C#:
    enum Days : int
    {
        Sunday = 1,
        Monday, Tuesday, Wednesday, Thursday, Friday,
        Saturday
    }
    
  • Each enum declaration introduces a new type.
  • As in Java, in C# and VB.NET a reference type can be:
    • a class type,
    • an interface type
    • an array type.
  • In every .NET language, there is one other kind of reference type:
    • a delegate type
    (which will be considered later).
  • If a value of some value type is supplied in a context that requires an object (an instance of some class type), an object will automatically be created.
  • This is called boxing.
  • Like Java, the .NET Framework has a collection class called ArrayList:
    ArrayList tArrayList = new ArrayList();
    
  • If i is an int:

    i = 27;
    tArrayList.Add(i);
    
    an object is automatically created.

  • If Point is a class type:

    Point tPoint = new Point(100, 200);
    tArrayList.Add(tPoint);
    

  • This is as in Java.
  • If instead we use a struct type, boxing takes place:

    SPoint tSPoint = new SPoint(300, 400);
    tArrayList.Add(tSPoint);
    

  • In Java, the only value types are the primitive types; and each primitive type has an associated wrapper type.
  • In Java, you have to do the boxing explicitly:
    int i = 27;
    Integer tInteger = new Integer(i);
    tArrayList.Add(tInteger);
    
  • In Java, a cast has to be used to get an object from an ArrayList.
  • This is also the case in C# and VB.NET.
  • If the cast is to a value type, unboxing automatically occurs.
  • This means the value of the object is copied into the variable:

    int j = (int) tArrayList[0];
    Point tGotPoint = (Point) tArrayList[1];
    SPoint tGotSPoint = (SPoint) tArrayList[2];
    

3.3.2. Methods

The following kinds of parameters are available:

Java C# VB.NET
value value ByVal
ref ByRef
out
params

private static void Swap(ref int x, ref int y)
{
    int temp = x;
    x = y;
    y = temp;
}
...
i = 42;
j = 27;
Swap(ref i, ref j);
// i has the value 27
// j has the value 42
  • As in C++, in C# a method is statically bound to its class unless the keyword virtual appears in the declaration of the method.
  • If a subclass wishes to override a method declared as virtual in a superclass, the keyword override must appear in the method's declaration in the subclass.
  • If a subclass does not wish to override but instead wishes to provide its own method as well, the keyword new must appear in the method's declaration in the subclass.
  • VB.NET instead uses the keywords Overridable, Overrides and Shadows.

3.3.3. Statements

  • The statements of C# are similar to those of Java.
  • C# also has a foreach statement:
    • to visit each element of a collection;
    • e.g., to visit each element of an array.
  • In C#'s switch statement, the selecting expression and the case labels may be strings:
    switch (tCommand)
    {
        case "add":
    	...
        case "remove":
    	...
    }
    
  • In C#'s switch statement, you must explictly code a fall through:
    tOp = -1;
    switch (tCommand)
    {
        case "add":
    	tOp = 1;
    	goto case "remove";
        case "remove":
    	...
    }
    

3.3.4. Properties, indexers and operator overloading

  • Besides fields, constructors and methods, in .NET languages a class type (or a struct type) may also declare properties.
  • A property should be used instead of providing get and/or set methods.
  • For example:
    public class Point
    {
        private int iX;
        private int iY;
        public Point(int pX, int pY)
        {
            iX  = pX;  iY = pY;
        }
        public int X
        {
            get { return iX;  } 
            set { iX = value; }
        }
        ...
    } 
    ...
    Point tPoint = new Point(100, 200);
    int  tX = tPoint.X;   // uses get
    tPoint.X = 150;       // uses set
    tPoint.X++;           // uses get and set
    
  • In C# (but not in VB.NET), a class type (or a struct type) may declare an indexer.
  • In the same way that a property provides access to a single value, an indexer provides access to an array of values.
  • In C# (but not in VB.NET), a class type (or a struct type) may declare operators.
  • An operator declaration permits a class (or a struct) to define new meanings for existing operators (such as ==, <, +, ++).
  • But not for =.

3.3.5. Delegates

  • A delegate is a type-safe function pointer.
  • Available in any .NET language.
  • A C# example is:
    delegate int Analyse(string s);
    
  • Suppose we also declare:
    private static int StringLength(string pString)
    {
        return pString.Length;
    }
    
  • We can now write:
    Analyse tAnalyse = new Analyse(StringLength);
    
    The variable tAnalyse now contains a pointer to the StringLength method.
  • A method can be written in terms of a parameter that is a delegate:
    private static void iProcess(Analyse pAnalyse)
    {
        string tString = Console.ReadLine();
        int tInt = pAnalyse(tString);
        Console.WriteLine(tInt);
    }
    
  • This contains the call:
    int tInt = pAnalyse(tString);
    
  • The function that is to be called can be supplied as an argument when iProcess is called:
    iProcess(tAnalyse);
    
  • If a delegate is a Sub in VB.NET or its return type is void in C#, a delegate variable can be assigned a value that represents (not just one method but) a list of methods to be called.

3.3.6. Events

  • One common use of a delegate is to register methods to be executed when an event occurs.
  • The namespace System declares the delegate:
    delegate void EventHandler(object sender, EventArgs e);
    
  • The class Button has a field called Click:
    public event EventHandler Click;
    
  • Suppose we declare an instance of the class Button:
    private Button iAddButton = new Button();
    
  • A method can be added to this Button's Click field using:
    iAddButton.Click += new EventHandler(iHandleClick);
    
  • Add the keyword event to the declaration of a delegate to restrict access to the delegate.
  • This assumes the existence of the method:
    protected void iHandleClick(object sender, EventArgs e)
    {
        ...
    }
    
  • All the above can be done in VB.NET instead of C#.

3.3.7. Exception handling

  • C# and VB.NET have similar constructs as Java for:
    • throwing an exception,
    • catching an exception.
  • Suppose the code of a method includes a statement that can cause an exception to occur:
    FileStream tFileStream = File.Open("data", FileMode.Open);
    
    This can cause the FileNotFoundException exception.
  • Suppose the code of the method does not want to handle this exception.
  • In Java, the header of the method declaration must document that the execution of the method may cause an exception to occur:
    private void iProcessFile() throws FileNotFoundException
    {
        ...
    }
    
  • In a .NET language, it is not necessary (and not possible) to do this.
  • One consequence is that, if you wish a method to catch all the exceptions that its code can throw, you cannot use the compiler to check whether you are doing this.

3.4. Not just the language

4. Four kinds of .NET applications

4.1. Console applications

Here is a program that reads in a temperature given in degrees Centigrade and outputs the corresponding value in degrees Fahrenheit:

using System;
namespace ConsoleConvert
{
    class Class1
    {
        [STAThread]
        static void Main()
        {
            Console.Write("Centigrade value: ");
            string tCentigradeString = Console.ReadLine();
            double tCentigrade = double.Parse(tCentigradeString);
            double tFahrenheit = 32 + tCentigrade*9/5;
            Console.WriteLine("Fahrenheit value: " + tFahrenheit);
        }
    }
}

4.2. Windows Forms applications

using System;
using System.Drawing;
using System.Windows.Forms;
namespace MyWindowsConvert
{
    public class Form1 : Form
    {
        private TextBox textBox1;
        private Button button1;
        private Label label1;
        public Form1()
        {
            textBox1 = new TextBox();
            textBox1.Location = new Point(64, 32);
            textBox1.Size = new Size(120, 20);
            Controls.Add(textBox1);
            button1 = new Button();
            button1.Location = new Point(64, 64);
            button1.Size = new Size(120, 20);
            button1.Text = "Get Fahrenheit";
            button1.Click += new EventHandler(button1_Click);
            Controls.Add(button1);
            label1 = new Label();
            label1.Location = new Point(64, 104);
            label1.Size = new Size(120, 20);
            Controls.Add(label1);
            Text = "MyWindowsConvert";
        }
        private void button1_Click(object sender, EventArgs e)
        {
            double tCentigrade = double.Parse(textBox1.Text);
            double tFahrenheit = 32 + tCentigrade*9/5;
            label1.Text = tFahrenheit.ToString();
        }
        public static void Main() 
        {
            Form1 tForm1 = new Form1();
            Application.Run(tForm1);
        }
    }
}

4.3. Web Form applications

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace WebFormConvert
{
    public class WebForm1 : Page
    {
        protected TextBox TextBox1;
        protected Button Button1;
        protected Label Label1;
        private void Page_Load(object sender, EventArgs e)
        {
        }
        override protected void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
        }
        private void InitializeComponent()
        {    
            this.Button1.Click += new System.EventHandler(this.Button1_Click);
            this.Load += new System.EventHandler(this.Page_Load);
        }
        private void Button1_Click(object sender, EventArgs e)
        {
            double tCentigrade = double.Parse(TextBox1.Text);
            double tFahrenheit = 32 + tCentigrade*9/5;
            Label1.Text = tFahrenheit.ToString();
        }
    }
}

4.4. Web Services

4.4.1. What is a Web Service?

  • A Web Service is a web server providing one or more methods that can be invoked by some external site.
  • In the .NET Framework, the code of each method can be written in any .NET language.
  • The external site can pass arguments to the method, and the method returns a result to the external site.
  • Web Services are an alternative to CORBA and Java's RMI.
  • The most flexible way is for the external site to send its message using HTTP POST where the body of the HTTP POST is in XML coded using SOAP:
    POST /barry.cornelius/moving/WebServerConvert/Service1.asmx HTTP/1.1
    Host: localhost
    Content-Type: text/xml; charset=utf-8
    Content-Length: XXXX
    SOAPAction: "http://www.dur.ac.uk/barry.cornelius/webservices/ToFahrenheit"
    
    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <ToFahrenheit xmlns="http://www.dur.ac.uk/barry.cornelius/webservices/">
          <pCentigrade>0</pCentigrade>
        </ToFahrenheit>
      </soap:Body>
    </soap:Envelope>
    
  • The response is also sent in XML coded using SOAP:
    HTTP/1.1 200 OK
    Content-Type: text/xml; charset=utf-8
    Content-Length: YYYY
    
    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <ToFahrenheitResponse xmlns="http://www.dur.ac.uk/barry.cornelius/webservices/">
          <ToFahrenheitResult>32</ToFahrenheitResult>
        </ToFahrenheitResponse>
      </soap:Body>
    </soap:Envelope>
    

4.4.2. Providing a Web Service

  • Visual Studio.NET has a wizard that generates the files necessary to provide a Web Service.
  • All you need do is to provide the code of each method flagging each method with a WebMethod attribute:
    [WebService]
    public class Service1 : System.Web.Services.WebService
    {
        ...
        [WebMethod]
        public double ToFahrenheit(double pCentigrade)
        {
            return 32 + pCentigrade*9/5;
        }
    }
    
  • An external site can now invoke the ToFahrenheit method by sending a request, e.g., using the SOAP given earlier.
  • Note that you do NOT write the code:
    • to decode the incoming HTTP requests,
    • to generate the XML of the reply.
    All of this is done elsewhere.

4.4.3. Accessing a Web Service

  • Suppose we now want to access the ToFahrenheit method.
  • Visual Studio.NET has a wizard that generates a proxy class.
  • You just supply the wizard with the URL of the Web Service.
  • The wizard queries the Web Service to discover the methods that it provides together with their signatures.
  • The wizard automatically generates the code of a class that has similar methods:
    public class Service1 : System.Web.Services.Protocols.SoapHttpClientProtocol
    {
        ...
        public double ToFahrenheit(double pCentigrade)
        {
            object[] results = this.Invoke("ToFahrenheit", new object[]{pCentigrade});
            return (double) results[0];
        }
        ...
    }
    
  • So the client of the Web Service just calls the method of the proxy class:
    Proxy.Service1 tService1 = new Proxy.Service1();
    double tFahrenheit = tService1.ToFahrenheit(tCentigrade);
    
  • When a method of the proxy class is called, the code of the method:
    • sends the appropriate SOAP request to the Web Service;
    • decodes the XML that is returned by the Web Service;
    • and returns an appropriate value to the caller of the method.
  • Note that you do NOT write the code:
    • to generate the HTTP request (and its XML),
    • to parse the XML of the reply.
    All of this is done by the code of the proxy class.
  • If you have not got Visual Studio.NET, you can instead generate a proxy class with a tool, called wsdl.exe, that is part of the .NET Framework (which is free).

5. Conclusions

6. References

  1. Ben Albahari, 'A Comparative Overview of C#', http://genamics.com/developer/csharp_comparative.htm
  2. Ben Albahari, Peter Drayton and Brad Merrill, 'C# Essentials (2nd edition)', O'Reilly, 2002, 0-596-00315-3.
  3. Barry Cornelius, 'A Taste of C#', http://www.dur.ac.uk/barry.cornelius/papers/a.taste.of.csharp/
  4. Barry Cornelius, 'Web Services', http://www.dur.ac.uk/barry.cornelius/papers/web.services/
  5. Harvey Deitel, Paul Deitel, J. Listfield, T. R. Nieto, Cheryl Yaeger, Marina latkina, 'C# How to Program', Prentice Hall, 2002, 0-13-062221-4.
  6. Eric Gunnerson, 'A Programmer's Introduction to C# (2nd edition)', Apress, 2001, 1-893115-62-3
  7. Billy Hollis and Rockford Lhotka, 'VB.NET Programming (With the Public Beta)', Wrox Press, 2001, 1-861004-91-5. Although this book is still useful, it has not been updated for Beta 2.
  8. Mark Johnson, 'C#: A language alternative or just J--?', http://www.javaworld.com/javaworld/jw-11-2000/jw-1122-csharp1.html
  9. Microsoft, 'C# Language Specification', http://msdn.microsoft.com/vstudio/nextgen/technology/csharpdownload.asp
  10. Microsoft, 'Visual Studio.NET and .NET Framework Reviewers Guide', http://msdn.microsoft.com/vstudio/nextgen/evalguidedownload.asp
  11. Microsoft, 'Visual Basic .NET Upgrade Guide', http://msdn.microsoft.com/vbasic/technical/upgrade/guide.asp
  12. Microsoft (MSDN UK), 'Visual Studio.NET Guided Tour', http://www.microsoft.com/uk/msdn/vstudiotour/tour.htm
  13. 'The Mono project', http://www.go-mono.com/
  14. Dare Obasanjo, 'A comparison of Microsoft's C# programming language to Sun Microsystem's Java programming language', http://www.25hoursaday.com/CsharpVsJava.html
  15. Thuan Thai and Hoang Q. Lam, '.NET Framework Essentials (2nd edition)', O'Reilly, 2002, 0-596-00302-1.



Date: 29th October 2002; first created: 12th January 2002 Author: Barry Cornelius.
This page is copyrighted