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 to Swift Programming Language for iOS, macOS, watchOS, tvOS and Linux development.

In this post, we will touch upon the key similarities between C# and Swift, precisely:

and other key Swift features. You can try the swift code snippets in the IBM Swift Sandbox, a tool that allows anyone to write and run Swift code from their browser. Learn about its features here

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, 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 3.0

//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(name: "Jones")
var employeeName = employee.getEmployee()
print("Employee is \(employeeName)")

Link to code in the IBM Swift Sandbox
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
{
   override init(name : String) {
     super.init(name: name) // Calls Employee(name)
    }
   //Method Overriding
   override func getEmployee() -> String {...}
}

We can achieve Multiple inheritance 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.

Note: Prevent override by using final modifier.
Link to code in the IBM Swift Sandbox

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 3.0,

//Protocol Declaration
protocol ProjectManager
{
 var projectName: String {get set}
 func getDeveloperCount() ->Int 
} 

//Implementation
class Manager : Employee,ProjectManager
{
 //Simple Property
 var managerName: String
 
 override init(name : String) {
 self.managerName = name
 super.init(name: name) // Calls Employee(name)
 }
 
 //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.
C# Console application output.

In Swift 3.0,

//List of Employee names
var names=["John","Johnes","Aria","Amar","Rajesh","Xavier"]

//Closure Expression
names=names.sorted(by: {(s1: String ,s2: String)-> Bool in return s2 > s1})

// for-in loop
for name in names {
    print(name)
}

Link to code in the IBM Swift Sandbox

IBM Swift Sandbox
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 3.0,

///Defining a generic function to swap two values
func swapTwoValues (_ a: inout T, _ b: inout 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)")

Link to code in IBM Swift Sandbox
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 & API Design Guidelines.

Also, Build powerful, fast and secure server side Swift apps for the Cloud.

Happy Swifting!!!

12 comments on"Swift for C# Developers"

  1. The Swift code could be more idiomatic (function names should be lower camel case, no underscore prefix for properties, print(name) instead of print(“\(name)”), etc.) but the comparison with C# is relevant. Maybe the goal is to make the Swift code samples as similar to the C# ones as possible, but I think this is a bit misleading to the Swift newcomer. Thanks for the article! 🙂

  2. Daniel Müllenborn February 26, 2016

    Protocols names should be capitalized in Swift.
    You should change the example like this:

    from
    protocol projectManager()
    to
    protocol ProjectManager

    and
    class Manager: Employee, IProjectManager
    to
    class Manager: Employee, ProjectManager

  3. Péter Ivanics February 28, 2016

    Thanks for this great overview! I am working with Swift for 6 months and used to develop in C# earlier. Too bad that I found it only now, but I still learned something new about Swift from here.

  4. Thanks for the article, but still I think syntax adaptation is not the issue here, it’s about learning the new ecosystem, tooling, and API.

  5. Chris Nevin April 01, 2016

    names=names.sort({(s1: String ,s2: String)-> Bool in return s2>s1})

    You could simplify this with the method ‘sortInPlace’, also you could mention that you can shorten this greatly using type inference and shorthand notation.

    i.e.
    names.sortInPlace({ $0 > $1 })

    • Chris Nevin April 01, 2016

      Also worth mentioning, but maybe not relevant to this primer for C# developers, is that the $0 > $1 is not required if your object implements the Comparable protocol (like the String’s in the example do). So this would just shortened even further to ‘names.sortInPlace()’.

  6. Nice article, I believe it is worth mentioning :

    There are some aspects of Swift (basically inspired by obj-c) that not fit in C#
    – extensions in Swift is more like partial classes in C#, you can specify protocols, static methods
    – protocols in Swift may contain interfaces and static methods

  7. * protocols in Swift may contain constructors and static methods
    – protocols may contain optional methods

Join The Discussion

Your email address will not be published. Required fields are marked *