5
5

More than 5 years have passed since last update.

Swift vs. C# : Extensions

Posted at
  • クラス継承をしないで機能拡張

Swift:

  • Add computed properties and computed static properties
  • Define instance methods and type methods
  • Provide new initializers
  • Define subscripts
  • Define and use new nested types
  • Make an existing type conform to a protocol

C#: Extension Methods

  • インスタンスメソッドが追加される(ように見える)

Extension Syntax

Swift:

extension SomeType: SomeProtocol, AnotherProtocol {
    // implementation of protocol requirements goes here
}

Computed Properties

  • Double を拡張するプロパティ
extension Double {
    var km: Double { return self * 1_000.0 }
    var m: Double { return self }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1_000.0 }
    var ft: Double { return self / 3.28084 }
}
  9> 10.0.km
$R0: Double = 10000

Initializers

  1> struct Size { 
  2.     var width = 0.0, height = 0.0 
  3. } 
  4. struct Point { 
  5.     var x = 0.0, y = 0.0 
  6. } 
  7. struct Rect { 
  8.     var origin = Point() 
  9.     var size = Size() 
 10. }
 12> extension Rect { 
 13.     init(center: Point, size: Size) { 
 14.         let originX = center.x - (size.width / 2) 
 15.         let originY = center.y - (size.height / 2) 
 16.         self.init(origin: Point(x: originX, y: originY), size: size) 
 17.     } 
 18. }
 19> let centerRect = Rect(center: Point(x: 4.0, y: 4.0), 
 20. size: Size(width: 3.0, height: 3.0))
centerRect: Rect = {
  origin = {
    x = 2.5
    y = 2.5
  }
  size = {
    width = 3
    height = 3
  }
}

Methods

  1> extension Int { 
  2.     func repetitions(task: () -> ()) { 
  3.         for i in 0..<self { 
  4.             task() 
  5.         } 
  6.     } 
  7. }
  8> 3.repetitions({ 
  9.     println("Hello!") 
 10.     })
Hello!
Hello!
Hello!

C#: Extension Methods

csharp> public static class Extensions {
      >     public static void Repeat(this int i , Action<int> act ){
      >          for(int x=0; x < i; x++ ) act(x);
      >     }   
      > }
csharp> 3.Repeat(delegate(int i){ Console.WriteLine(string.Format("{0} *** \n",i));});

0 *** 

1 *** 

2 *** 

Mutating Instance Methods

  • 破壊的
  1> extension Int { 
  2.     mutating func square() { 
  3.         self = self * self 
  4.     } 
  5. }
  6> var someInt = 3
someInt: Int = 3
  7> someInt.square()
  8> someInt
$R0: Int = 9

Subscripts

  1> extension Int { 
  2.     subscript(var digitIndex: Int) -> Int { 
  3.         var decimalBase = 1 
  4.         while digitIndex > 0 { 
  5.             decimalBase *= 10 
  6.             --digitIndex 
  7.         } 
  8.         return (self / decimalBase) % 10 
  9.     } 
 10. }
 11> 746381295[0]
$R0: Int = 5
 12> 746381295[1]
$R1: Int = 9

Nested Types

  1> extension Int { 
  2.     enum Kind { 
  3.         case Negative, Zero, Positive 
  4.     } 
  5.     var kind: Kind { 
  6.         switch self { 
  7.         case 0: 
  8.             return .Zero 
  9.         case let x where x > 0: 
 10.             return .Positive 
 11.         default: 
 12.             return .Negative 
 13.         } 
 14.     } 
 15. }
 17> 3.kind
$R0: Int.Kind = Positive

 18> (-1).kind
$R1: Int.Kind = Negative

 19> 0.kind
$R2: Int.Kind = Zero

C# Dynamic Type

C# Dynamic :

Dynamic is advanced functionality.
It can be useful.
But usually it should be avoided.
It erases many benefits of the C# language.

Dynamic Object
(StackOverFlow):

  • Dictionaryのホルダーを内部に持って、System.Dynamic.DynamicObjectのメソッドのオーバーライドでごにょごにょする
using System.Dynamic;

class DynamicDuck : DynamicObject 
{
      Dictionary<string, object> dictionary
           = new Dictionary<string, object>();
    public int Count
    {   
        get { return dictionary.Count; }
    }   
    public override bool TryGetMember(
          GetMemberBinder binder, out object result)
    {   
          string name = binder.Name.ToLower();
            return dictionary.TryGetValue(name, out result);
    }   
    public override bool TrySetMember(
         SetMemberBinder binder, object value)
    {   
          dictionary[binder.Name.ToLower()] = value;
          return true;
    }   
 }
dynamic d = new DynamicDuck();
d.firstname = "Gideon";
d.Quack = (Action)(() => Console.WriteLine("Quack by " + d.firstname));
d.Quack();
Quack by Gideon
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5