rainit2006 / C-Program

C# Program knowledge
0 stars 0 forks source link

数据类型:Tuple,Array,Dic, コレクションクラス #25

Open rainit2006 opened 6 years ago

rainit2006 commented 6 years ago

rainit2006 commented 6 years ago

Tuple, 元组 Tuple类型像一个口袋,在出门前可以把所需的任何东西一股脑地放在里面。C# 4.0引入的一个新特性 Tuple类型与口袋类似,它可以存放不同类型的对象。

在C# 4.0之前我们函数有多个返回值,通常是使用ref,out 。到了c# 4.0 应当使用元组Tuple而不是使用输出参数,在任何时候都应避免使用ref/out传递参数,尤其对引用类型(禁止引用的引用,尝试改进你的设计。

数组合并了相同类型的对象,而元组合并了不同类型的对象。元组起源于函数编程语言(如F#) ,在这些语言中频繁使用元组。.NET 4定义了8个泛型Tuple类和一个静态Tuple类,它们用作元组的工厂。这里的不同泛型Tuple类支持不同数量的元素。例如,Tuple包含-个元素,Tuple<T1,T2>包含两个元素,以此类推。

var date = Tuple.Create<int, int, int>(2009, 5, 29);
Console.writeLine(date.item1);  // 输出2009
rainit2006 commented 6 years ago

https://qiita.com/hiki_neet_p/items/75bf39838ce580cca92d image

ObservableCollectionクラスは、ユーザーインターフェイスとコレクションの同期したい場合などに使用されます。


using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

class Sample {
  static void Main()
  {
    ObservableCollection<int> col = new ObservableCollection<int>();

    // コレクション変更のイベントを受け取るハンドラを設定
    col.CollectionChanged += PrintCollectionChanged;

    // 要素の追加
    col.Add(0);
    col.Add(1);
    col.Add(2);
    col.Add(3);
    col.Add(4);

    Print(col);

    // 要素の削除
    col.Remove(1);
    col.Remove(3);

    Print(col);

    // 特定の位置にある要素を削除
    col.RemoveAt(1);

    Print(col);

    // 特定の位置にある要素を変更
    col[0] = 5;

    Print(col);

    // 特定の位置に要素を挿入
    col.Insert(1, 6);

    Print(col);

    // 特定の位置にある要素を別の位置に移動
    col.Move(2, 0); // インデックス2の要素をインデックス0に移動

    Print(col);
  }

  static void PrintCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  {
    Console.WriteLine(e.Action);
  }

  static void Print(ObservableCollection<int> col)
  {
    foreach (int e in col) {
      Console.Write("{0}, ", e);
    }

    Console.WriteLine();
  }
}

実行結果
Add
Add
Add
Add
Add
0, 1, 2, 3, 4, 
Remove
Remove
0, 2, 4, 
Remove
0, 4, 
Replace
5, 4, 
Add
5, 6, 4, 
Move
4, 5, 6, 

なお、ObservableCollectionにはSortやReverseといった並べ替えのメソッドは用意されていませんが、拡張メソッドのOrderByメソッドやOrderByDescendingメソッドを使うことでコレクションをソートした結果を得ることが出来ます. 参考:http://smdn.jp/programming/netfx/collections/3_objectmodel_2_observablecollection/

rainit2006 commented 6 years ago

std::vector (C++) 動的配列クラス.

image

std::vector<int> data(123);  //  int 型で、初期要素数 123 の動的配列 data の宣言
 std::vector<int> data(10, 5);      //  要素数10、全ての要素の値5 で初期化

std::vector<int> org{1, 2, 3};
std::vector<int> x(org);      // コピーコンストラクタ

std::vector<int> v;       // 空の動的配列を生成
v.push_back(123);     // 末尾に 123 を追加

v.push_back(T(コンストラクタ引数)); //新規クラスオブジェクトをコンテナ末尾に追加する

std::vector<int> v{3, 1, 4, 1, 5};
v.pop_back();    //  末尾データ(この場合は 5)を削除

 for(auto itr = v.begin(); itr != v.end(); ++itr) {
        *itr でイテレータの指す要素を参照
    }
rainit2006 commented 6 years ago

http://u1roh.hatenadiary.jp/entry/2014/02/28/183243

C++/C# コレクション(コンテナ) image これらは System.Collections.Generic 名前空間に定義されています。 System.Collections 直下にあるクラスは黒歴史なので使わないで下さい。 C# の List と C++ の std::list を混同しないように注意して下さい。 C++ の set/map は二分木によるものですが、C# の HashSet や Dictionary はハッシュテーブルによるものですので、正確にはこれらは異なるものです。そういう意味では対応づけるべきではないのかもしれませんが、用途としては似ている場面が多いと思いますので上のような表にしました。 正直なところ、C++STLの方が自由度が高く高機能かと思います。

IEnumerable インターフェイス C++のSTLコンテナでは、コンテナ要素にアクセスするための統一的な方法として iterator を提供しています。全てのコンテナは begin(), end() を提供.

C#では(.NETでは)この IEnumerable インターフェイスがコレクション要素にアクセスするための統一的な機能として用意されています。全てのコレクションは IEnumerable を実装

//C++

ContainerType c;
for (ContainerType::iterator it = c.begin(); it != c.end(); ++it) {
  ...
}
//C#

CollectionType c;
foreach (var item in c) {
  ...
}
//C#
using System.Linq;

IEnumerable<int> sequence = new[] { 1, 3, 7, 6, 4, 2, 9 };

// (A) メソッドチェイン形式
var q1 = sequence
  .Where( i => i % 2 == 0 ).OrderBy( i => i ).Select( i => i % 3 );
//sequence から偶数のみを取り出し、昇順に並べ替えて、3で割った余りに変換」を表しています。