Skip to main content

[From C# to Swift] 11. Methods

Instance Methods
#

1. Core Concepts
#

  • Concept Explanation: Instance methods are functions that belong to instances of a specific type (class, structure, enumeration). They encapsulate the logic for manipulating that instance.
  • Key Syntax: func

2. Example
#

class Counter {
    var count = 0
    func increment() {
        count += 1
    }
    func increment(by amount: Int) {
        count += amount
    }
    func reset() {
        count = 0
    }
}

let counter = Counter()
counter.increment()
counter.increment(by: 5)
counter.reset()

Logic Explanation: This code defines a Counter class containing three instance methods.

  1. increment(): Takes no arguments, directly accesses and modifies the internal count property.
  2. increment(by:): Demonstrates Swift’s argument label feature, making calls more readable.
  3. Calling style uses dot syntax (.), consistent with most object-oriented languages.

3. C#
#

Concept Correspondence: This corresponds to Instance Methods in C#.


The self Property
#

1. Core Concepts
#

  • Concept Explanation: Every instance has an implicit property called self, representing the instance itself. Usually, you don’t need to write self explicitly unless a naming conflict occurs (e.g., when a parameter name is the same as a property name), in which case self is needed for distinction.
  • Key Syntax: self

2. Example
#

struct Point {
    var x = 0.0, y = 0.0
    func isToTheRightOf(x: Double) -> Bool {
        return self.x > x
    }
}

Logic Explanation: In the isToTheRightOf method, the parameter name is x, and the property name is also x. To disambiguate, Swift uses self.x to refer to the instance property, while the standalone x refers to the parameter.

3. C#
#

Concept Correspondence: Equivalent to the this keyword in C#.

C# Example:

struct Point {
    public double X;
    public double Y;
    
    public bool IsToTheRightOf(double x) {
        // C# uses this to disambiguate
        return this.X > x;
    }
}

Key Difference Analysis:

  • Syntax: Except for the keyword spelling (self vs this), usage is consistent.

Modifying Value Types from Within Instance Methods
#

1. Core Concepts
#

  • Concept Explanation: Swift’s Structures and Enumerations are Value Types. Within a non-mutating instance method, you cannot modify self or its properties. If modification is required, you must add the mutating keyword before the method declaration.
  • Key Syntax: mutating
  • Note:

Note: You cannot call a mutating method on a structure instance that is a constant (let), because properties of a constant structure are completely immutable.

2. Example
#

struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
// Point is now at (3.0, 4.0)

let fixedPoint = Point(x: 3.0, y: 3.0)
// fixedPoint.moveBy(x: 2.0, y: 3.0) // This line will report an error

Logic Explanation: The moveBy method modifies x and y. Since Point is a Struct, it must be marked as mutating. When the method ends, these changes are written back to the original structure.

3. C#
#

Concept Correspondence: C# Structs are mutable by default, unless declared as readonly struct. C# does not have a mutating marker for individual methods.

C# Example:

struct Point {
    public double X;
    public double Y;

    // C# struct methods can modify fields by default (though Mutable Structs are not recommended)
    public void MoveBy(double deltaX, double deltaY) {
        X += deltaX;
        Y += deltaY;
    }
}

Key Difference Analysis:

  • Behavior: Swift’s design is safer. If you declare let p = Point(...), the compiler will forbid calling any mutating methods.

Assigning to self Within a Mutating Method
#

1. Core Concepts
#

  • Concept Explanation: In a mutating method, you can not only modify properties but also assign a completely new instance to the implicit self property. This is particularly useful in state switching logic for Enumerations (Enum).

2. Example
#

enum TriStateSwitch {
    case off, low, high
    mutating func next() {
        switch self {
        case .off:
            self = .low
        case .low:
            self = .high
        case .high:
            self = .off
        }
    }
}

Logic Explanation: This is a “three-state switch” enumeration. The next() method checks the current self state and directly replaces self with the next state (.low, .high, etc.). This is a minimalist implementation of a Finite State Machine (FSM).

3. C#
#

Concept Correspondence: C# Enums cannot define methods, nor can they mutate themselves.

Key Difference Analysis:

  • Syntax: Swift Enums can have state and behavior. C# Enums are merely numeric constants.
  • Behavior: Swift allows Enums to mutate themselves via mutating methods. C# requires relying on Extension Methods and returning a new value, or moving the logic to an external class.

Type Methods
#

1. Core Concepts
#

  • Concept Explanation: Methods that belong to the type itself rather than a single instance are called type methods.
    • For Struct and Enum, use the static keyword.
    • For Class, you can use static (cannot be overridden by subclasses) or class (allows override by subclasses).
  • Key Syntax: static func, class func

2. Example
#

class SomeClass {
    class func someTypeMethod() {
        // Implement type method here
    }
}
SomeClass.someTypeMethod()

struct LevelTracker {
    static var highestUnlockedLevel = 1
    var currentLevel = 1

    static func unlock(_ level: Int) {
        if level > highestUnlockedLevel { highestUnlockedLevel = level }
    }

    static func isUnlocked(_ level: Int) -> Bool {
        return level <= highestUnlockedLevel
    }  
}

Logic Explanation: LevelTracker uses static to define unlock and isUnlocked methods. These methods manage global game progress (highest unlocked level) without relying on specific player instances.

3. C#
#

Concept Correspondence: Equivalent to static methods in C#.

C# Example:

class SomeClass {
    // C# static methods cannot be overridden (unless using static abstract in interfaces - C# 11+)
    public static void SomeTypeMethod() { }
}

struct LevelTracker {
    public static int HighestUnlockedLevel = 1;
    
    public static void Unlock(int level) {
        if (level > HighestUnlockedLevel) HighestUnlockedLevel = level;
    }
}

Key Difference Analysis:

  • Syntax:
    • static vs class: This is the most important point for C# developers to note.
      • Swift’s static func in a Class is equivalent to C# static (Final, cannot be overridden).
      • Swift’s class func in a Class corresponds to a concept that has no direct equivalent in C# (can be thought of as an “inheritable static method”), allowing subclasses to override class func to provide their own implementation.