Swift for C# Developers
Programming languages provide a way to communicate with a computer through notational instructions. Swift and C# are high-level languages commonly categorized under multi-paradigm and compiled programming languages. They not only fall into the same category of programming languages but also have many syntactical features in common. Due to this syntactical resemblance, C# developers can easily adapt Swift Programming Language for iOS, OS X, watchOS, tvOS, and Linux development. In this post, we will touch upon the key similarities between C# and Swift. You can try the swift code snippets in IBM Swift Sandbox, a tool that allows anyone to write and run Swift code from their browser.
Const is Let and Var is Still Var
A Constant is an identifier with a value which cannot be modified during the normal execution of a program. In C#, Constants are defined using keyword const and the syntax for defining a constant is
const {Type} {ConstantName} = Value;
const int loginAttempts = 3;
In Swift, constants are defined using let and explicitly defining a type is optional as it picks the datatype based on the "value" which is provided.
let {ConstantName} : {Type} = Value
let loginAttempts = 3
let loginAttempts:Int = 3
A semicolon (;) at the end of each statement is optional in Swift. However, semicolons are required if you want to write multiple separate statements on a single line.
let loginAttempts=3;
print(loginAttempts)
Note: In C#, When defining a constant symbol, its value must be determinable at compile time. Whereas in Swift, the value of a constant doesn’t need to be known at compile time, but must have a value assigned exactly once with explicit type defined. Similar to C#, var is the keyword to define a variable in Swift.
// C# - Implicitly typed local variable
var name = "Sagar";
//Swift
var name = "Sagar"
var name : String = "Sagar"
Note: As C#, Swift is also type safe.It performs type checks when compiling your code and flags any mismatched types as errors. This enables you to catch and fix errors as early as possible in the development process.
Classes and Objects
A class is a blueprint defining the data and behavior of a type. An object is an instance of a class created dynamically with a block of memory allocated. Properties, methods, and fields are the members of a class. In C#,
//class definition
class Employee
{
//Field
private String _employeeName;
//Property
public String EmployeeName
{
get{ return _employeeName; }
set{ _employeeName = value; }
}
//Constructor or Initializer
public Employee(String name)
{
this.EmployeeName = name;
}
//Method
public String GetEmployee()
{
return EmployeeName;
}
//Destructor
~Employee()
{
//Cleanup Statements
}
}
//Instance Creation - Object
var employee= new Employee("James");
var employeeName = employee.GetEmployee();
Similarly, in Swift
//Class Definition
class Employee()
{
//Property
//Similar to a var but declared in a class.
var name: String
//Property with getter and setter
var employeeName : String {
get {
return name
}
set {
name= newValue
}
}
//Initializer or Constructor
init(name: String) {
//self is similar to 'this' in C#
self.name = name
}
//Method
func getEmployee() -> String {
return employeeName
}
//DeInitializer
deinit
{
}
}
//Instance Creation - Object
var employee = Employee("Jones")
var employeeName = employee.getEmployee()
Note: Methods are functions that are associated with a particular type. Also, if a method accepts more than one parameter, named arguments can be used the same way as in C#. E.g., var employee = Employee(name: "Jones", Id: 12345).
Class and Interface (Protocol in Swift) Inheritance
Inheritance is one of the primary pillars of object-oriented programming. Inheritance is all about reusability of the code. A new class can be created from an existing class.
// C#
// Manager is termed as Sub / Derived class.
// Employee is termed as Super / Base class.
class Manager : Employee
{
public Manager(String name) : Base(name) // Calls Employee(name)
//Method Overriding
//Only If the method in base class is marked as "virtual"
public override String GetEmployee(){...}
}
// Swift
class Manager: Employee
{
init(name : String) {
super.init(name: name) // Calls Employee(name)
}
//Method Overriding
override func getEmployee() -> String {...}
}
We can achieve multiple inheritances through Interfaces in C# and protocols in Swift. interfaces and protocols are just contracts without any implementation. The syntax is similar to the class declaration. In C#,
// Interface Definition
Interface IProjectManager
{
String projectName{ get; set;}
Int GetDeveloperCount();
}
//implementation
class Manager : Employee, IProjectManager
{
//Field
private String _name;
//Property
public String projectName{
get{
return _name;
}
set{
_name=value;
}
//Method
public Int GetDeveloperCount()
{
return 15;
}
}
In Swift,
//Protocol Declaration
protocol ProjectManager()
{
var projectName: String {get set}
func getDeveloperCount() ->Int
}
//Implementation
class Manager: Employee,ProjectManager
{
//Simple Property
var name: String
//Property with getter and setter
var projectName: String {
get {
return name
}
set {
name = newValue
}
}
//Method
func getDeveloperCount() -> Int {
return 15
}
}
Lambdas are Closures in Swift
Lambda expression introduced in version 3.0 of C# language is an expression which returns a method. The expression lambdas are expressed in the following basic form in C#,
(input parameters) => expression
In Swift, the Closure expression takes the following general form,
{ (parameters) -> return type in statements }
Sorting a list of names is a herculean task for any developer. So here's an example showcasing the beauty of lambdas/Closures.
In C#,
Note: Just for the sake of comparison and understanding, I am using a C# console application for the code snippets below.
class Program
{
static void Main(string[] args)
{
//List of names
var names = new List{ "John","Johnes","Aria","Amar","Rajesh","Xavier"};
names.Sort((s2, s1) => s2.CompareTo(s1));
foreach (var name in names)
{
Console.WriteLine(name);
}
Console.ReadLine();
}
}
Once you run the code in Visual Studio, You should see an output as shown in the figure below. C# Console application output.
In Swift,
//List of Employee names
var names=["John","Johnes","Aria","Amar","Rajesh","Xavier"]
//Closure Expression
names=names.sort({(s1: String ,s2: String)-> Bool in return s2 > s1})
// for-in loop
for name in names {
print(name)
}
Swift output as seen in IBM Swift Sandbox (in a browser) IBM Swift Sandbox
Generics are Generics in Swift
C# provides generics to remove the need for casting, improve type safety, reduce the amount of boxing required, and make it easier to create generalized classes and methods. The generic code enables you to write flexible, reusable functions and types that can work with any type, subject to requirements that you define. Generics in C#,
class Program
{
//Generic method
static void SwapTwoValues<T>(ref T a, ref T b)
{
T temp;
temp = a;
a = b;
b = temp;
}
static void Main(string[] args)
{
// Swap two values
int a = 40, b = 60;
Console.WriteLine("Before swap: {0}, {1}", a, b);
SwapTwoValues<int>(ref a, ref b);
Console.WriteLine("After swap: {0}, {1}", a, b);
Console.ReadLine();
}
}
Generics in Swift,
///Defining a generic function to swap two values
func swapTwoValues(inout a: T, inout _ b: T) {
let temporaryA = a
a = b
b = temporaryA
}
//Usage of swapTwoValues
var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
// \() - String Interpolation
print("After Swap:\(someInt),\(anotherInt)")
Note:
- If you do not want to use an external name for the second or subsequent parameters of a function, write an underscore (_) instead of an explicit external name for that parameter.
- Swift uses string interpolation to include the name of a constant or variable as a placeholder in a longer string and to prompt Swift to replace it with the current value of that constant or variable.
Along with the features mentioned above, Swift provides some power features which makes coding smooth and bug-free.
- Optionals: Optionals say either “there is a value, and it equals x” or “there isn’t a value at all- nil.” In a way, Similar to nullable types in C# but optionals are more expressive and safe. Check unwrapping to understand what I mean.
- Optional Chaining: Think of a scenario where we are calling a method or talking to a property depending on an optional which might currently be nil. Swift provides an option to gracefully cut the method call or property talk if the optional is nil. Note: Optional chaining is an alternative to Forced unwrapping
- ARC: Object life cycle management is an overhead for a developer as it has a direct impact on memory management which affects the app performance. Here comes automatic reference counting (ARC) to the rescue, when an instance is no longer needed, ARC frees up the memory used by that instance so that the memory can be used for other purposes instead. This ensures that class instances do not take up space in memory when they are no longer needed. It looks like garbage collection (GC) in .Net world but the approach is different. Which one is better? The answer is always debatable.
- Guard: Guard is a conditional statement which helps in an Early Exit if a condition is not met. Unlike an if statement, a guard statement always has an else clause—the code inside the else clause is executed if the condition is not true. Also, any variables or constants that were assigned values using an optional binding as part of the condition are available for the rest of the code block that the guard statement appears in.
- Property Observers: To observe and respond to changes in a property’s value property observers are called. Property observers are called every time a property’s value is set, even if the new value is the same as the property’s current value. You have the option to define either or both of these observers on a property:
- willSet is called just before the value is stored.
- didSet is called immediately after the new value is stored.
- willSet and didSet cannot be called when a property is set in an Initializer - init
What we discussed till now is just a drop in the ocean. There are many features which have similar syntax in C# and Swift. Structs, enums, loops (control flow) are few of them which you can explore and if you are struck anywhere feel free to drop a comment in the comments section below.
What's Next?
Check Official Swift Documentation
Happy SWIFTing!!!