University of Oxford |
|
Computing Services |
|
From C++ to C# |
|
Author: Barry Cornelius Date: 31st July 2002; first created: 27th July 2002 |
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 |
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 ... .’
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++.’
Here is a list of some of the features that are not included in C#:
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.
#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; }
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; public class PointTest { public static void Main() { Point tPoint = new Point(100, 200); Console.WriteLine(tPoint); Point tAnotherPoint = tPoint; Console.WriteLine(tAnotherPoint); } }
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; 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#.
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.
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).
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, ... .
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 |
ArrayList tArrayList = new ArrayList();
i = 27; tArrayList.Add(i);an object is automatically created.
Point tPoint = new Point(100, 200); tArrayList.Add(tPoint);
If instead we use a struct type, boxing takes place:
SPoint tSPoint = new SPoint(300, 400); tArrayList.Add(tSPoint);
int i = 27; Integer tInteger = new Integer(i); tArrayList.Add(tInteger);
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];
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
delegate int Massage(string s);
private static int StringLength(string pString) { return pString.Length; }
Massage tMassage = new Massage(StringLength);The variable tMassage now contains a pointer to the StringLength method.
private static void iProcess(Massage pMassage) { string tString = Console.ReadLine(); int tInt = pMassage(tString); Console.WriteLine(tInt); }
int tInt = pMassage(tString);
iProcess(tMassage);
delegate void EventHandler(object sender, EventArgs e);
public event EventHandler Click;
private Button iAddButton = new Button();
iAddButton.Click += new EventHandler(iHandleClick);
protected void iHandleClick(object sender, EventArgs e) { ... }
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
switch (tCommand) { case "add": ... case "remove": ... }
tOp = -1; switch (tCommand) { case "add": tOp = 1; goto case "remove"; case "remove": ... }
FileStream tFileStream = File.Open("data", FileMode.Open);This can cause the FileNotFoundException exception.
private void iProcessFile() throws FileNotFoundException { ... }
BufferedReader tKeyboard = new BufferedReader(new InputStreamReader(System.in)); String tAgeString = tKeyboard.readLine(); int tAge = Integer.parseInt(tAgeString);
string tAgeString = Console.ReadLine(); int tAge = int.Parse(tAgeString);
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); } } }
Form Button TextBox Label MainMenu MenuItem
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); } } }
<%@ ... language="c#" Codebehind="WebForm1.aspx.cs" ... Inherits="WebFormConvert.WebForm1" %> <form id="Form1" ... > <asp:TextBox id="TextBox1" ... </asp:TextBox> <asp:Button id="Button1" ... Text="Get Fahrenheit" ... </asp:Button> <asp:Label id="Label1" ... </asp:Label> </form>
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(); } } }
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>
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>
[WebService] public class Service1 : System.Web.Services.WebService { ... [WebMethod] public double ToFahrenheit(double pCentigrade) { return 32 + pCentigrade*9/5; } }
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]; } ... }
Proxy.Service1 tService1 = new Proxy.Service1(); double tFahrenheit = tService1.ToFahrenheit(tCentigrade);