C# for Java Programmers Flashcards
Keywords from Java reused in C
- Control flow: if, else, do, while, for, switch, case, default, break, continue, try, catch, finally, throw
- Operators: ., (), [], */%, +-, <, ==, &&, ||, =
- Primitive types: bool (true, false), byte, char, int, long, float, double
- Classes and objects: class, interface, abstract, static, volatile, new, null, this
- Methods: public, private, protected, void, return
Keywords from Java changed in C
extends
,implements
:
super
base
final
readonly
,sealed
import
using
package
namespace {...}
instanceof
is
synchronized
lock x
finalize()
~ClassName()
(clean-up called by garbage collector)
C# Enhancements
- Generics: C#
List<T>
uses a!0[]
array, avoiding type erasure and casting, unlike Java'sArrayList<T>
which usesObject[]
. - Switch with strings: Supported directly in C#.
- Autoboxing/Autounboxing: Not needed in C#.
- Try-with-resources: C# uses the
using
statement. - Enumerated types: Supported in C#.
- Enhanced for loop: C# uses the
foreach
loop. - Varargs: C# uses the
params
keyword. - Static imports: C# uses
using
extension methods. - Lambda expressions: Supported in C#.
Examples of C# Enhancements
- Using Statement:
csharp using (FileStream fs = File.OpenRead(path)) using (StreamReader sr = new StreamReader(fs)) { string line; while ((line = sr.ReadLine()) != null) { Console.WriteLine(line); } }
- Enum Definition and Usage:
csharp enum TrafficLightColour {Red, RedAmber, Green, Amber}; TrafficLightColour tlc = TrafficLightColour.Red;
- Foreach Loop:
csharp string[] presidents = new string[] { “Washington”, “Jefferson”, “Lincoln”, “Roosevelt” }; foreach (string president in presidents) { Console.WriteLine(president); }
- Params Keyword:
csharp public static void SumList(params int[] list)
- Lambda Expressions:
csharp int[] somevalues = { 10, 20, 5, 2, 40, 1 }; int numberOfLargeValues = somevalues.Count(x => x >10);
Differences in Control Flow
- Each non-empty
case
in aswitch
statement must end with abreak
statement (orreturn
,goto
,throw
). goto
can be used to jump out of a nestedfor
loop.- No checked exceptions (no
throws
list on method declarations). - Exception handling is less rigid.
- An expression or a block can be checked using the
checked
keyword to throw aSystem.OverflowException
if an overflow occurs.- Example:
csharp int x = 1000000; int y = checked(x*x);
- Example:
Switch Statement for a Finite State Machine
int state = 0; // begins in state 0
int ch = Console.Read(); // reads first transition symbol
switch (state)
{
case 0:
if (ch=='a') {ch = Console.Read(); goto case 1;}
else if (ch=='c') goto case 2;
else goto default;
case 1:
if (ch=='b') {ch = Console.Read(); goto case 1;}
else if (ch=='c') goto case 2;
else goto default;
case 2:
Console.WriteLine(“Input valid!”); break;
default:
Console.WriteLine(“Illegal character: “ + (char) ch); break;
}
Differences in Types
- Unsigned types:
byte
,ushort
,uint
,ulong
(for systems programming). decimal
type: For large decimal numbers with high accuracy (financial mathematics).- Uniform Type System (UTS): All types inherit from
System.Object
.- Can have a
List<int>
and insertint
without boxing.
- Can have a
- Managed pointers:
&T
is the type of a managed pointer toT
.int& i
means CLR will check at runtime thati
is pointing to anint
(type-safe).
- Unmanaged pointers:
*T
is the type of an unmanaged pointer toT
.int* i
means CLR will not do such checks, and arithmetic operations are possible (only inunsafe
blocks).
Structs
Lightweight objects for holding temporary data.
Held on the stack (no garbage collection).
Value types: copying has value semantics.
- Copy
p
toq
and changeq
, thenp
won’t change.
- Copy
Objects are reference types: copying has reference semantics.
- Copy
p
toq
and changeq
, thenp
will also change.
- Copy
Example:
struct Point { public int x, y; // fields public Point(int x, int y) {this.x = x; this.y = y;} public void MoveTo(int x, int y) {this.x = x; this.y = y;} } Point q = p; // How to copy Point p to q
Block Matrices
- Java represents matrices as arrays of arrays (can be jagged).
- C# allows block matrices of uniform dimensions.
- Examples:
csharp int[,] a = new int[2,3]; int[,] b = {{1, 2, 3}, {4, 5, 6}}; int[,,] c = new int[2,4,2];
Dynamic Typing
- Designed to support dynamically typed languages (e.g., IronPython).
- Defers binding and dispatch operations to runtime.
- Example:
csharp dynamic s = GetObject(); Console.WriteLine(s.ToUpper()); // object s doesn’t work
- Do not confuse with
var
, where the type is inferred statically. - Example:
csharp var numbers = new List<int>();
Properties
No need to write type signatures for getters and setters.
Can use the record syntax to “invisibly” call them both.
Example:
class Person { private string name; // field public string Name { // property get {return name;} set {name = value;} // often omitted } } Person p = new Person(); p.Name = “Ian”; Console.WriteLine(p.Name);
Auto-implemented Properties (C# 3.0+)
- If getters and setters are trivial, C# can derive them.
- The same class with auto-implemented properties:
csharp class Person { public string Name { get; set; } }
Indexers
- Properties that can be indexed, i.e., accessed like an array.
- Implemented as an invisible property
Item
. - Example:
csharp class Vector { private int x, y, z; public Vector (int x, int y, int z) { this.x=x; this.y=y; this.z=z; } public int this[int index] { // Indexer declaration get { // e.g., v[2] if v has type Vector if (index == 0) return x; else if (index == 1) return y; else if (index == 2) return z; else throw new ArgumentOutOfRangeException(); } // setter omitted to save space, uses value as before } }
Reference Parameters
In Java, all parameter passing is by value.
In C#, using the
ref
keyword, passing can be by reference.- The reference parameter represents the same storage location as the variable given as the actual parameter.
Using the
out
keyword, the variable need not be assigned first.Example:
static void Swap(ref int x, ref int y) { int temp = x; x = y; y = temp; } static void Main() { int i = 1, j = 2; Swap(ref i, ref j); // now i = 2, j = 1 }
Modifiers: new
and override
If a method in a subclass shares its name with a method in a base class, this will cause a warning.
Use
new
oroverride
to indicate that this is intentional.override
indicates that the new method is a replacement.new
indicates that the old method should still exist but be hidden.Example:
public class BaseC { public int x; public void Invoke() { } } public class DerivedC : BaseC { new public void Invoke() { } }
Using yield return
for Lazy Evaluation
Example:
public class PowersOf2 { static void Main() { foreach (int i in Power(2, 8)) { Console.Write("{0} ", i); } }
}public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent) { int result = 1; for (int i = 0; i < exponent; i++) { result = result * number; yield return result; } // returns number^0 ... number^(exponent-1) }
LINQ (=Language Integrated Query)
- Lazy evaluation used to implement LINQ.
- Like SQL but from arrays, data structures, XML documents, etc.
- Example (preferred standard syntax):
csharp var results = from c in SomeCollection where c.SomeProperty < 10 select new {c.SomeProperty, c.OtherProperty};
- The pair returned is an instance of an anonymous type.
- LINQ in a more informative but awkward syntax:
csharp var results = SomeCollection .Where(c => c.SomeProperty < 10) .Select(c => new {c.SomeProperty, c.OtherProperty});
Using Delegates (like Command Pattern)
Example:
delegate int BinOp(int a, int b); // BinOp is now a class providing an Invoke method static class DelegateExample { static int Add (int a, int b) { return a+b; } static void Main() { BinOp add = new BinOp(Add); int three = add(1,2); // called the Invoke method on the BinOp object } }
Reading Material
- C# in Depth Jon Skeet 2019
- .NET Application Development Hanspeter Mössenböck et al
- msdn.microsoft.com (see Moodle links)
- practice, practice, practice