We now look at some of the ways in which C# and
Visual Basic.NET are different from Java.
- Value types
- Reference types
- Boxing
- Unboxing
- Methods
- Statements
- Properties
- Indexers
- Operators
- Delegates
- Events
- Exception handling
-
The value types
are the
struct types,
primitive types
and enumeration types.
-
The declaration of a struct type is similar to that of a class
type.
-
For example,
it can declare fields, constructors and
methods.
-
However, the big difference is:
a variable
that is of some class type
points to an object of that class
whereas a variable
that is of some struct type
stores the value itself.
-
So assignment between two structs causes copying
of a struct value to take place
rather than making a variable point to the same object
as some other variable.
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:
(which will be considered later).
-
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);
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.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.