49
C# -> Swift Richard Ekle Email: [email protected] Twitter: @rekle

C# to Swift - files.meetup.comfiles.meetup.com/1748372/C# to Swift.pdfConstants C#: Swift: const int x = 5; const string y = “Hello”; let x = 5 let y = “hello”

Embed Size (px)

Citation preview

C# -> Swift

Richard Ekle Email: [email protected]

Twitter: @rekle

Swift is the futureNOT the present

• Missing features • Optimization issues

C# and Swift Versions

• C# 5.0 - Visual Studio 2012 or later, .NET 4.5

• Swift 1.0 beta 3 - Xcode 6 beta 3

Swift Playgrounds

VariablesC#: explicit type (typical)

Swift: type inference (typical)

int x = 5; int y; // Defaults to 0 int a = 0, b = 1, c = 2;

var x = 5 var a = 0, b = “hello”, c = XYZ()

C#: type inferencevar x = 5; var y; // Error. Must be initialized

Swift: explicit typevar x: Int = 5 var y: Int // OK, but a value must be assigned before use

ConstantsC#:

Swift:

const int x = 5; const string y = “Hello”;

let x = 5 let y = “hello”

SemicolonsC#: required

Swift: optional

int x = 5; int y = 6; int z = 7; int a = 8;

var x = 5 var y = 6 // Required if multiple statements on one line var z = 7; var a = 8

CommentsC#:

Swift:

// Single line comment /* Multiline comment /* Nested comments generate error */ */

// Single line comment /* Multiline comment /* Nested comments work */ */

Primitive typesC#:

Swift:

int x = 5; Int16 y = 6; Int32 z = 7; Int64 a = 8; uint x = 5; UInt16 y = 6; UInt32 z = 7; UInt64 a = 8; double y = 4.5; float z = 1.25F; string name = “John 😃”; // Unicode string char a = ‘👀’; // Unicode character Boolean isVisible = true;

var x: Int = 5; var y: Int16 = 6; var z: Int32 = 7; var a: Int64 = 8 var x: UInt = 5; var y: UInt16 = 6; var z: UInt32 = 7; var a: UInt64 = 8 var y: Double = 4.5 var z: Float = 1.25 var name: String = “John 😃” // Unicode string var a: Character = “👀” // Unicode character var isVisible: Bool = true

Integer boundsC#:

Swift:

Int32 x = Int32.MaxValue; Int32 y = Int32.MinValue;

var x = Int32.max var y = Int32.min // Same for other Int, UInt types

Type ConversionC#:

Swift:

Double x = 5.56; int y = (int)x; // 5 Double z = (Double)y; // 5.0

var x:Double = 5.56 var y = Int(x) // 5 var z = Double(y) // 5.0

EnumerationsC#: always integral values

Swift: not integral values

enum Colors { Red, // 0 Green, // 1 Blue = 5 // 5 } Colors c = Colors.Red;

enum Colors { case Red case Green case Blue } var c: Colors = .Red // Explicit type c = .Green var d = Colors.Red // Type inferred d = .Blue

Enumerationswith non-integral types

C#: not supported

Swift: enum with character type

enum ControlChar: Character { case Tab = “\t” case LineFeed = “\n” case CarriageFeed = “\r” } var c = ControlChar.Tab // use toRaw() to get the raw value (\t, \n etc.) println(“\(c.toRaw())Test”) // Prints “<tab>Test”

Enumerationswith associated values

C#: not supported

Swift: enum with associated valuesenum Color { case RGB(Int,Int,Int) case RGBA(Int,Int,Int,Int) } var c = Color.RGB(255, 0, 0) var d: Color = .RGBA(0, 255, 0, 128)

OptionalsC#: nullable type

Swift: optionals

int? x = 5; int? y = null;

var x:Int? = 5 var y:Int? = nil

Optional UnwrappingC#: nullable type

Swift: optionals

int? x = 5; if (x.HasValue) Console.WriteLine(“x has the value {0}”, x.Value);

var x:Int? = 5 if let xVal = x { println(“x has the value \(x!)”) // x! or xVal }

Optional ChainingSwift:class ClassA { func AFunc() -> Int { return 5 } } class ClassB { var a:ClassA? } var b:ClassB? // Possibly allocate b if let aVal = b?.a?.AFunc() { println(“aVal = \(aVal)”) } else { println(“not defined”) }

Array initializationC#:

Swift:

// Immutable array string[] names = { “Sam”, “Pete” }; // Mutable array List<string> names2 = new List<string>();

// Mutable arrays var names: [String] = [] // Explicit type var names2 = [String]() // Inferred type var names3 = Array<String>() // Inferred type // Mutable array. Type inferred as Array<String> var names4 = [“Sam”, “Pete”] // Immutable (const) array. Type inferred as Array<String> let names4 = [“Sam”, “Pete”]

Array insert/deleteC#:

Swift:

List<string> names = new List<string>(); names.Add(“John”); names.Add(“Mike”); names.Remove(“John”); Console.WriteLine(names[0]); // “Mike” Console.WriteLine(names.Count); // 1

var names = [String]() // Mutable names.append(“John”) names.append(“Mike”) names.removeAtIndex(0) println(“\(names[0])”) // Mike println(“\(names.count)”) // 1 let names2 = [“John”, “Mike”] // Immutable names2.append(“Sam”) // Error. Immutable array

Dictionary initializationC#:

Swift:

Dictionary<string,int> children = new Dictionary<string,int>();

// Mutable Dictionaries. var children = [String:Int]() // Type inferred var children2 = Dictionary<String,Int>() // Type inferred var children3 = [String:Int] = [:] // Type inferred var children4: Dictionary<String,Int> = [:] // Explicit type var children5: [String:Int] = [:] // Explicit type // Mutable Dictionary. Type inferred as Dictionary<String,Int> var children4 = [“John”: 3, “Mike”: 2] // Immutable Dictionary. Type inferred as Dictionary<String,Int> let children5 = [“John”: 3, “Mike”: 2]

Dictionary insert/deleteC#:

Swift:

Dictionary<string,int> children = new Dictionary<string,int>();children.Add(“John”, 3); children.Add(“Mike”, 2); children.Remove(“John”);

var children = [String:Int]() // Mutable children[“John”] = 3 children[“Mike”] = 2 let children2 = [“John”: 3, “Mike”: 2] // Immutable children[“Sam”] = 4 // Error. Immutable dictionary

if / elseC#:

Swift:

// Parenthesis required, braces optional if ( x == 5 ) Console.WriteLine(“true”); else Console.WriteLine(“false”);

// Parenthesis optional, braced required if x == 5 { println(“true”) } else { println(“false”) }

whileC#:

Swift:

// Parenthesis required, braces optional while ( x > 0 ) x -= 1;

// Parenthesis optional, braced required while x > 0 { x -= 1 }

do whileC#:

Swift:

// Parenthesis required, braces optional do x -= 1; while (x > 0);

// Parenthesis optional, braced required do { x -= 1 } while x > 0

for loopsC#:

Swift:

// Parenthesis required, braces optional for (int i=0; i < 5; i++) Console.WriteLine(i);

// Parenthesis optional, braced required for var i = 0; i < 5; i++ { println(i) }

for in loopsC#: foreach

Swift: for in

// Parenthesis required, braces optional string[] names = new string[]{ “John”, “Mike”, “Sam”}; foreach(var currName in names) Console.WriteLine(currName);

// Parenthesis optional, braced required var names = [“John”, “Mike”, “Sam”] for currName in names { println(currName) }

switchC#: implicit case fall through

Swift: no implicit case fall through

switch (x) { case 1: Console.WriteLine(“1”); break; case 2: case 3: case 4: case 6: Console.WriteLine(“2, 3, 4 or 6”); break; // Does not have to be exhaustive }

switch x { case 1: println(“1”) case 2…4, 6: println(“2, 3, 4 or 6”) case 7: println(“7”) fallthrough // causes this case to fall through to default default: // Switch must be exhaustive println(“Other”) }

Global functionsC#: Not supported

Swift:

// Takes two Int values as input // and returns an Int func Add( x: Int, y: Int ) -> Int { return x + y }"

Add(2,4)

Global functions with external parameter names

C#: Not supported

Swift:

// Takes two Int values as input // and returns an Int func Add( externalX x: Int, externalY y: Int ) -> Int { return x + y }"

Add(externalX:2, externalY:4)

ProtocolsC#: Interface

Swift: Protocol

public interface ABC { int SomeFunc(); void SomeFunc2(); }

protocol ABC { func SomeFunc() -> Int func SomeFunc2() }

ClassesC#:

Swift:

class XYZ { // Initialized to 0. int x; }

class XYZ { // Must be initialized. var x: Int; }

Class InheritanceC#: single inheritance only

Swift: single inheritance only

class XYZ: BaseClass { }

class XYZ: BaseClass { }

Class implementing protocol

C#: interface

Swift: protocol

class XYZ: InterfaceName { }

class XYZ: ProtocolName { }

Class inheritance andprotocol implementation

C#: Base class comes before interface

Swift: Base class comes before protocol

class XYZ: BaseClass, Interface1, Interface2 { }

class XYZ: BaseClass, Protocol1, Protocol2 { }

InitializersC#: constructor

Swift: initializer

class XYZ { int x; XYZ() { x = 5; } } XYZ x = new XYZ()

class XYZ { var x: Int // Type required for class properties init() { x = 5 } } var x = XYZ()

Initializers with parametersC#: constructor

Swift: initializer

class XYZ { int x; XYZ(int newX) { x = newX; } } XYZ x = new XYZ(5); // Param names not required

class XYZ { var x: Int // Type required for class properties init(newX: Int) { x = 5 } } var X = XYZ(newX: 5) // param names required

DeinitializersC#: destructor

Swift: deinitializer

class XYZ { ~XYZ() { } }

class XYZ { deinit { } }

Allocating objectsC#:

Swift:

XYZ x = new XYZ();

var x = XYZ();

Memory ManagementC#:

Swift:

Garbage Collection

ARC (Automatic Reference Counting)

selfC#: this

Swift: self

class X { int x; X() { this.x = 5; } }

class X { var x: Int; init() { self.x = 5; } }

Computed PropertiesC#:

Swift:

public class XYZ { public string firstName, lastName; public string FullName { get { return firstName + “ “ + lastName; } } } var x = new XYZ(); x.firstName = “John”; x.lastName = “Smith”; Console.WriteLine(x.FullName);

class XYZ { var firstName: String, lastName: String var FullName: string { get { return firstName + “ “ + lastName } } } var x = XYZ(); x.firstName = “John”; x.lastName = “Smith” println(“\(x.FullName)”);

Instance MethodsC#:

Swift:

class XYZ { void VoidFunc() { /* body */ } int IntFunc() { return 5; } }

class XYZ { func VoidFunc() { /* body */ } func IntFunc() -> Int { return 5 } }

Instance methodswith parameters

C#:

Swift:

class XYZ { int AddFunc(int x, int y) { return x+y; } } XYZ x = new XYZ(); int y = x.AddFunc(5,10);

class XYZ { func AddFunc(x:Int, y:Int) -> Int { return x+y } } var x = XYZ() // Swift: No first param name. The rest required var y = x.AddFunc(5, y:10) // Objective-C XYZ *x = [[XYZ alloc] init]; int y = [x AddFunc:5 y:10];

Instance methodswith parameters having external names

Swift:class XYZ { func AddFunc(theX x:Int, theY y:Int) -> Int { return x+y } func AddFunc2(theX x:Int, y:Int) -> Int { return x+y } } var x = XYZ() // Swift: All external param names required var y = x.AddFunc(theX:5, theY:10) var y = x.AddFunc2(theX:5, y:10)

Type MethodsC#:

Swift:

class XYZ { static void VoidFunc() { /* body */ } static int IntFunc() { return 5; } } XYZ.VoidFunc(); int y = XYZ.IntFunc();

class XYZ { class func VoidFunc() { /* body */ } class func IntFunc() -> Int { return 5 } } XYZ.VoidFunc() var y = XYZ.IntFunc()

Overriding methodsand accessing super class

C#:

Swift:

class A { virtual string AFunc() { return “A”; } } class B: A { override string AFunc() { return base.AFunc() + “B”; } }

class A { func AFunc() -> String { return “A” } } class B: A { override func AFunc() -> String { return super.AFunc() + “B” } }

Method OverloadingC#:

Swift:

class A { int AFunc(int x) { return x; } int AFunc(double x) { return (int)x*2; } }

class A { func AFunc(x: Int) -> Int { return x } func AFunc(x: Double) -> Int { return Int(x)*2 } }

Preventing class inheritance

C#:

Swift:

sealed class A { } // Error: A is sealed. Can’t derive from it. class B: A { }

@final class A { } // Error: A is final. Can’t derive from it. class B: A { }

GenericsC#:

Swift:

class ABC<T> { T someValue; } ABC<string> x = new ABC<string>();

class ABC<T> { var someValue: T? } var x = ABC<String>()