1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swift vs. C#: Generics

Posted at

Swift : Generics

C#: ジェネリック (C# プログラミング ガイド)

The Problem That Generics Solve

  • 省略

Generic Functions

  1> func swapThem<T>(inout a: T, inout b: T) { 
  2.     let t = a ;a = b; b = t  
  3. }
  4> var a = 0, b = 2 
a: Int = 0
b: Int = 2
  5> println("\(a) \(b)") 
  6. swapThem(&a, &b) 
  7. println("\(a) \(b)")
0 2
2 0

  8> var i = "Apple", j = "Banana"
  9> println("\(i) \(j)")

Apple Banana
  
 10> swapThem(&i,&j)
 11> println("\(i) \(j)")

Banana Apple

C#:

public class Generic 
{
  public static void Swap<T>(ref T a , ref T b )
  {
     var t = a ;
     a = b ; b = t;
  }
}
var x  = 0;
var y  = 3;
Console.WriteLine(string.Format("{0} {1}", x, y ));
Generic.Swap(ref x , ref y );
Console.WriteLine(string.Format("{0} {1}", x, y ));

var  i = "Apple";
var  j = "Banana";
Console.WriteLine(string.Format("{0} {1}", i, j ));
Generic.Swap(ref i , ref j );
Console.WriteLine(string.Format("{0} {1}", i, j ));


0 3
3 0
Apple Banana
Banana Apple

Type Parameters

  • "T"のこと

Tが使えるのは

  • 引数型
  • 返り値型
  • 型アノテーション(変数の型宣言)

C#: おなじ

Naming Type Parameters

  6> func swapThem<TYPE1>(inout a: TYPE1, inout b: TYPE1) { 
  7.     let t = a ;a = b; b = t 
  8. }
  1> func print<T1, T2>(a : T1, b : T2 ){ 
  2.    println("\(a) \(b)") 
  3. }

C#: 同じ

Generic Types

struct Stack<T> {
    var items = [T]()
    mutating func push(item: T) {
        items.append(item)
    }
    mutating func pop() -> T {
        return items.removeLast()
    }
}

C#: Stack Class

Extending a Generic Type

extension Stack {
    var topItem: T? {
        return items.isEmpty ? nil : items[items.count - 1]
    }
}

C#: Exetnsion Method を定義する

	public static class Extensions 
	{
		public static T topItem<T>(this Stack<T> stack)
		{
			return stack.First ();
		}   
	}
var top = mystack.topItem();

Type Constraints

Type Constraint Syntax

Type Constraints in Action

 17> func Employ<T: Person>(person : T) 
 18. { 
 19.    println("\(person.name) is employed.")                                                                                                              
 20. }
 21> Employ(Student(name:"Bob"))
Bob is employed.

Type Method

 16. class Employee : Person {  
 17.   class func employ<T: Person>(p: T) -> Employee 
 18.   { 
 19.       return Employee(name:p.name)  
 20.   } 
 21. }  
 22> Employee.employ( Student(name:"Cindy") )
$R0: Employee = {
  __lldb_expr_1.Person = {
    name = "Cindy"
  }
}

C#: where。

public class Company 
{
    public static Employee Employ<T>(T person) where T: Person
    {
        return new Employee(){name = person.name};
    }
}


var e = Company.Employ(new Student(){name="Bob"});
Console.WriteLine(e.GetType() );
Employee

Associated Types

Associated Type = alias name + Type

An associated type gives a placeholder name (or alias) to a type that is used as part of the protocol.

typealias がキーワード

C#: Associated Type的な物はないと思います

Associated Types in Action

  • 要するにGenericの型指定のコンクリートクラスを定義するときに typealias を使えるっぽい

Swift:

protocol Container {
    typealias ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

struct IntStack: Container {

    // original IntStack implementation
    var items = [Int]()
    mutating func push(item: Int) {
        items.append(item)
    }
    mutating func pop() -> Int {
        return items.removeLast()
    }

    typealias ItemType = Int
    mutating func append(item: Int) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Int {
        return items[i]
    }
}

C#: Tに型を入れて実装/継承、でいいんじゃないでしょうか。

public interface IContainer<T> { 
    void append(T item);
    int count { get; }
    T this[int i] { get; }
}

public class IntStack : IContainer<int>
{
    public void append(int item) {}
    public int count { get { return 0; }}
    public int this[int i] { get { return 0; }}
}

Extending an Existing Type to Specify an Associated Type

Swift: extensionでジェネリックタイプを注入

extension Array: Container {}

C#: Extension メソッドでやるか、継承したサブクラスを定義(ただしクラスは多重継承できない)

Where Clauses

Swift: 型制約に加えて、 whereを使って、Associated Typeの制約を加えられるようです

func allItemsMatch<
    C1: Container, C2: Container
    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
    (someContainer: C1, anotherContainer: C2) -> Bool {
        
        // check that both containers contain the same number of items
        if someContainer.count != anotherContainer.count {
            return false
        }
        
        // check each pair of items to see if they are equivalent
        for i in 0..<someContainer.count {
            if someContainer[i] != anotherContainer[i] {
                return false
            }
        }
        
        // all items match, so return true
        return true
        
}

C# Generis

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?