unimportant logo identifying Barry Cornelius

University of Oxford

Computing Services

From C++ to C#

  Author: Barry Cornelius Date: 31st July 2002; first created: 27th July 2002

Contents

1. Introduction

This talk has the following 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# Managed C++ Visual Basic.NET
System.Boolean 8 bool bool Boolean
System.Byte 8 byte char Byte
System.Int16 16 short short Short
System.Int32 32 int int or long Integer
System.Int64 64 long __int64 Long
System.Single 32 float float Single
System.Double 64 double double Double
System.Char 16 char __wchar_t Char
System.Decimal 128 decimal System::Decimal Decimal

2.5. Language interoperability

2.6. Tool support

2.7. Deployment

2.8. Versioning

3. Which language?

3.1. What languages are available?

3.2. What about C++?

The WWW page http://codeguru.earthweb.com/20AsWithRichter.shtml has an article that is entitled '20 .NET and C# Questions with Jeffrey Richter'. One of the questions is: We've seen managed extensions, but aside from that, what future does C++ have at MS and in .NET? Here is Jeffery Richter's reply:

‘C++ is unique in that it is the only Microsoft language that allows the developer to write managed and unmanaged code. So, I can easily see developers writing in unmanaged C++ for performance-critical algorithms and then using managed C++ for type-safety and component interoperability. I'm sure Microsoft will keep C++ going for years to come: device drivers need it, Windows is built with it, SQL Server, Exchange, and other BackOffice products will probably use C++ for a long, long time.’

The WWW page http://www.eponymous.eclipse.co.uk/csharpfaq.htm contains 'C# Frequently Asked Questions for C++ programmers'. The page is maintained by Andy McMullan. His answer to the question Does C# replace C++? is:

‘The obvious answer is no. However it's difficult to see C++ as the best choice for new .NET code. For the .NET runtime to function fully, it requires the programming language to conform to certain rules - one of these rules is that language types must conform to the Common Type System (CTS). Unfortunately many C++ features are not supported by the CTS - for example multiple inheritance of classes and templates.’

‘Microsoft's answer to this problem is to offer Managed Extensions (ME) for C++, which allows you to write C++ that conforms to the CTS. New keywords are provided to mark your C++ classes with CTS attributes (e.g. __gc for garbage collection). However, it's difficult to see why ME C++ would be chosen over C# for new projects. In terms of features they are very similar, but unlike C++, C# has been designed from the ground-up to work seamlessly with the .NET environment. The raison d'etre for ME C++ would therefore appear to be porting existing C++ code to the .NET environment.’

‘So, in answer to the question, my suspicion is that C++ will remain an important language outside of the .NET environment, and will be used (via ME) to port existing code to .NET, but I think C# will become the language of choice for one-time C++ developers developing new .NET applications. But only time will tell ... .’

3.3. Why C#?

The WWW page http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsent7/html/vxconProgrammingLanguages.asp gives Microsoft's view of the role of various programming languages in the .NET Framework. Here is what they say about C#:

‘Visual C# (pronounced C sharp) is designed to be a fast and easy way to create .NET applications, including Web services and ASP.NET Web applications. Applications written in Visual C# are built on the services of the common language runtime and take full advantage of the .NET Framework.’

‘C# is a simple, elegant, type-safe, object-oriented language recently developed by Microsoft for building a wide range of applications. Anyone familiar with C and similar languages will find few problems in adapting to C#. C# is designed to bring rapid development to the C# programmer without sacrificing the power and control that are a hallmark of C and C#. Because of this heritage, C# has a high degree of fidelity with C and C#, and developers familiar with these languages can quickly become productive in C#. C# provides intrinsic code trust mechanisms for a high level of security, garbage collection, and type safety. C# supports single inheritance and creates Microsoft intermediate language (MSIL) as input to native code compilers.’

‘C# is fully integrated with the .NET Framework and the common language runtime, which together provide language interoperability, garbage collection, enhanced security, and improved versioning support. C# simplifies and modernizes some of the more complex aspects of C and C#, notably namespaces, classes, enumerations, overloading, and structured exception handling. C# also eliminates C and C# features such as macros, multiple inheritance, and virtual base classes. For current C++ developers, C# provides a powerful, high-productivity language alternative.’

Andy McMullan's 'C# Frequently Asked Questions for C++ programmers' says:

‘C# is a programming language designed by Microsoft. It is loosely based on C/C++, and bears a striking similarity to Java in many ways.’

The WWW page http://genamics.com/developer/csharp_comparative.htm contains a paper by Ben Albahari entitled 'A Comparative Overview of C#'. In the conclusion to this paper, he says:

‘Overall, I believe C# provides greater expressiveness and is more suited to writing performance-critical code than Java, while sharing Java's elegance and simplicity, which makes both much more appealing than C++.’

3.4. What's been taken out from C/C++?

Here is a list of some of the features that are not included in C#:

4. Types in C#

As mentioned earlier, the CLS says that each .NET language must provide:

As well as value types and reference types, C# also has pointer types. These can only be used in code marked as unsafe. So, we will ignore pointer types.

5. Reference types

5.1. Class types

#pragma once
#include <iostream>
using namespace std;
class Point
{
public:
    Point(const int pX = 0, const int pY = 0);
    friend ostream& operator <<(ostream &, const Point &);
private:
    int iX;
    int iY;
};
#include "point.h"
Point::Point(const int pX, const int pY)
:iX(pX), iY(pY)
{
}
ostream& operator <<(ostream& os, const Point& pPoint)
{
    os << pPoint.iX << ':' << pPoint.iY;
    return os;
}
#include "point.h"
int main()
{
    Point* tPoint = new Point(100, 200);
    cout << *tPoint << endl;
    Point* tAnotherPoint = tPoint;
    cout << *tAnotherPoint << endl;
    return 0;
}

5.2. A Point class in C#

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;
    }
}

5.3. Using the Point class in C#

using System;
public class PointTest
{
    public static void Main()
    {
        Point tPoint = new Point(100, 200);
        Console.WriteLine(tPoint);
        Point tAnotherPoint = tPoint;
        Console.WriteLine(tAnotherPoint);
    }
}

5.4. Inheritance in C#

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();
    }
}

5.5. Using the derived class in C#

using System;
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 C#:

If it were necessary, a mix of .NET languages could be used. For example, we could use a NamedPointTest class coded in C# with a NamedPoint class coded in VB.NET and a Point class coded in C#.

5.6. Garbage collection

C/C++ programs inadvertently free/delete objects which are still in use:

int *p, *q;                 int *p, *q;
p = malloc(sizeof(int));    p = new int;
*p = 27;                    *p = 27;
q = p;                      q = p;
free(p);                    delete p;
printf("%d\n", *q);         cout << *q << endl;
And programs often cause memory leaks by not using free/delete on unwanted objects.

Like Java, in C# you do not delete objects: instead, these languages have garbage collection. The garbage collector detects objects no longer in use, and reuses their space.

5.7. Interface types

In its simplest form, an interface declaration just gives a list of method headers. An interface declaration should be introduced when you want to document that a class satisfies an interface, i.e., that it provides each of the methods listed in the interface declaration.

With a class, we use new and a constructor to create an instance of the class. It does not make sense to create an instance of an interface (and for this reason an interface does not have a constructor).

5.8. Array types

In C#, it is possible to create one-dimensional arrays, multi-dimensional arrays or jagged arrays. Here is an example of the declaration of an array of ints:

int[] months = new int[12];
This makes a variable (called months) point to an object that has room for 12 ints. The usual notation is used to access an array element. If an index is out-of-range, an exception will be produced. The class System.Array provides a number of useful methods that can be applied to arrays, such as Sort, BinarySearch, Reverse, ... .

5.9. Delegate types

The final kind of reference type is the delegate type. We will look at delegate types later.

6. Value types

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

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;
public class SPointTest
{
    public static void Main()
    {
        SPoint tSPoint = new SPoint(100, 200);
        Console.WriteLine(tSPoint);
        SPoint tAnotherSPoint = tSPoint;
        Console.WriteLine(tAnotherSPoint);
    }
}

In C#, each primitive type is just an alias for a struct type.

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

7. Other aspects of types

7.1. Boxing

7.2. Properties

7.3. Indexers and operator overloading

7.4. Delegates

7.5. Events

7.6. 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

7.7. Statements

7.8. Exceptions

8. Not just the language

9. Four kinds of .NET applications

9.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);
        }
    }
}

9.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);
        }
    }
}

9.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();
        }
    }
}

9.4. Web Services

9.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>
    

9.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.

9.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).

10. Conclusions

11. 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, 'Comparing .NET with Java', http://www.dur.ac.uk/barry.cornelius/papers/comparing.dotnet.with.java/
  5. Barry Cornelius, 'Web Services', http://www.dur.ac.uk/barry.cornelius/papers/web.services/
  6. Harvey Deitel, Paul Deitel, J. Listfield, T. R. Nieto, Cheryl Yaeger, Marina Zlatkina, 'C# How to Program', Prentice Hall, 2002, 0-13-062221-4.
  7. Kate Gregory, 'Special Edition Using Visual C++.NET', Que, 2002, 0-7897-2466-9.
  8. Eric Gunnerson, 'A Programmer's Introduction to C# (2nd edition)', Apress, 2001, 1-893115-62-3
  9. Mark Johnson, 'C#: A language alternative or just J--?', http://www.javaworld.com/javaworld/jw-11-2000/jw-1122-csharp1.html
  10. Joseph Mayo, 'C# Unleashed', SAMS, 2001, 0-672-32122-X.
  11. Andy McMullan, 'C# Frequently Asked Questions for C++ programmers', http://www.eponymous.eclipse.co.uk/csharpfaq.htm
  12. Klaus Michelsen, 'C# Primer Plus', SAMS, 2001, 0-672-32152-1.
  13. Microsoft, 'C# Language Specification', http://msdn.microsoft.com/vstudio/nextgen/technology/csharpdownload.asp
  14. Microsoft, 'Visual Studio.NET and .NET Framework Reviewers Guide', http://msdn.microsoft.com/vstudio/nextgen/evalguidedownload.asp
  15. Microsoft, 'Visual Basic .NET Upgrade Guide', http://msdn.microsoft.com/vbasic/technical/upgrade/guide.asp
  16. Microsoft (MSDN UK), 'Visual Studio.NET Guided Tour', http://www.microsoft.com/uk/msdn/vstudiotour/tour.htm
  17. Microsoft, 'Programming Languages', http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsent7/html/vxconProgrammingLanguages.asp
  18. 'The Mono project', http://www.go-mono.com/
  19. Dare Obasanjo, 'A comparison of Microsoft's C# programming language to Sun Microsystem's Java programming language', http://www.25hoursaday.com/CsharpVsJava.html
  20. Jeffrey Richter, '20 .NET and C# Questions with Jeffrey Richter', http://codeguru.earthweb.com/20AsWithRichter.shtml
  21. Jeffrey Richter, 'Applied Microsoft .NET Framework Programming', Microsoft Press, 2002, 0-7356-1422-9.
  22. Chris Sells, 'Managed C++: From ATL/COM to .NET', http://www.develop.com/conferences/conferencedotnet/materials/M4.pdf
  23. Thuan Thai and Hoang Q. Lam, '.NET Framework Essentials (2nd edition)', O'Reilly, 2002, 0-596-00302-1.



Date: 31st July 2002; first created: 27th July 2002 Author: Barry Cornelius.
This page is copyrighted