C#のHashSetでDictionaryのKeyのみのリスト(コレクション)的な使い方ができるよ

HashSetコレクション型
https://msdn.microsoft.com/ja-jp/library/bb397727(v=vs.110).aspx

簡単に言うと、HashSetクラスは値のないDictionary<TKey, TValue>コレクションです。
つまりHashSetを使うと、DictionaryのKey部分のみのような使い方ができます。順序が不要な重複しない要素のリストで使います。

Containsメソッドで要素が存在するかをチェックすることもできますが、Addメソッドの戻り値を使って、要素が既に存在するかを知ることもできます。

HashSetのAddメソッドでは要素がすでに存在していても、Dictionaryのように例外は発生せずにfalseが返ってきます。

シンプルなサンプル

var codeList = new List<int>() 
{ 
    1, 2, 3, 1,
};

var codeKeys = new HashSet<int>();
foreach(var code in codeList)
{
    if (codeKeys.Add(code) == false) continue;

    // なんか処理
}

var cnt = codeKeys.Count;// 3

C# Formアプリケーション関連のイベント発生順

↓を見ればわかります…最初に知りたかったよ~(´・ω・`)

Windowsフォームのイベントの順序
https://msdn.microsoft.com/ja-jp/library/86faxx0d(v=vs.110).aspx
Windowsフォームにおけるマウスイベント
https://msdn.microsoft.com/ja-jp/library/ms171542(v=vs.110).aspx

 

Windowsフォームアプリケーションが起動したとき

メインフォームのスタートアップイベントが次の順序で発生します。

Control.HandleCreated
Control.BindingContextChanged
Form.Load
Control.VisibleChanged
Form.Activated
Form.Shown

 

Windowsフォームアプリケーションを閉じたとき

メインフォームのシャットダウンイベントが次の順序で発生します。

Form.Closing
Form.FormClosing
Form.Closed
Form.FormClosed
Form.Deactivate

 

フォーカスイベントと検証イベント

一般に、
フォーカスを得たとき → Enterイベント(GotFocusイベントは使わない)
フォーカスが外れたとき → Leaveイベント(LostFocusイベントは使わない)
昔はGotFocus・LostFocusを使っていたそうですが、今はEnter・Leaveを使います。

◼︎パターン1

以下の方法でフォーカスを変更したとき

・キーボード (Tab、Shift + Tab など) を使用する
・Select メソッドを呼び出す
・SelectNextControl メソッドを呼び出す
・ActiveControl プロパティを現在のフォームに設定する

次の順序で Control クラスのフォーカス イベントが発生します。

Enter
GotFocus
Leave
Validating
Validated
LostFocus


◼︎パターン2

以下の方法でフォーカスを変更したとき

・マウスの使用
・Focus メソッドの呼び出し

次の順序で Control クラスのフォーカス イベントが発生します。

Enter
GotFocus
LostFocus
Leave
Validating
Validated

 

マウスイベント

次の順序で発生します。

MouseEnter
MouseMove
MouseHover / MouseDown / MouseWheel
MouseUp
MouseLeave

 

マウスボタンのシングルクリックイベント

Windowsフォームのコントロールで、
Button、CheckBox、ComboBox、RadioButton以外は、
次の順序でクリックイベントが発生します。左右ボタンのどちらにも以下の順序で発生します。

MouseDown
Click
MouseClick
MouseUp

 

マウスボタンのダブルクリックイベント

Windowsフォームのコントロールでは、次の順序でイベントが発生します。
(Button、CheckBox、ComboBox、RadioButton以外)

MouseDown
Click
MouseClick
MouseUp
MouseDown
DoubleClick
MouseDoubleClick
MouseUp

 

DoubleClickイベントについて
コントロールのStandardDoubleClickスタイルビットがtrueに設定されているかどうかによって異なる場合があります。

 

グレープシティのイベント

FlexGrid for WinFormsにはBeforeMouseDownイベント(MouseDownイベントを処理する前に発生)などいろいろな便利イベントが準備されています。

 

C#でLINQを使ったToDictionaryの使い方(ListからDictionaryを作成、DictionaryからDictionaryを作成)

.NET Framework3.5(C#3.5)から使えます。
バージョンが低くて使えない時は、forやforeachで回すしかありません(´・ω・`)

構文

Enumerable.ToDictionary メソッド
https://msdn.microsoft.com/ja-jp/library/system.linq.enumerable.todictionary(v=vs.110).aspx

//        戻り値           メソッド名 
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
    this IEnumerable<TSource> source,// 拡張メソッド(拡張する型を指定)
    Func<TSource, TKey> keySelector// System.Func<TSource, TKey>型
)

オーバーロードで4つのメソッドがありますがよく使うのは以下の2つだと思います。
・引数が1つ
・引数が2つ

ListからDictionaryを作成

ToDictionaryを使ってListからDictionaryを作ることが簡単にできます。

// 【1-1】引数が1つ
// Valueを指定しない場合
// IdをKey、UserオブジェクトをValueとしたディクショナリを作成
Dictionary<int, User> userDic1 = this.Users.ToDictionary(x => x.Id);

// 【1-2】引数が2つ
// IdをKeyに、NameをValueとしたディクショナリを作成
var userDic2 = this.Users.ToDictionary(x => x.Id, x => x.Name);

DictionaryからDictionaryを作成

ToDictionaryを使えばDictionaryから新しいDictionaryを作ることも簡単にできます。

// 【2-1】引数が1つ
// ValueはuserDic1の<Key, Value>がそのまま入ってくる
// 1-1と同じ使い方。
var userDic3 = userDic1.ToDictionary(x => x.Key);

// 【2-2】引数が2つ
// Keyを多少変更してディクショナリを作り直した例
// 1-2と同じ使い方。
var userDic4 = userDic1.ToDictionary(x => x.Key.ToString().PadLeft(3, '0'), x => x.Value);

サンプルコード全体

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ToDictionarySample
{
    public partial class Form1 : Form
    {
        // ユーザーリスト
        public List<User> Users { get; set; }

        // コンストラクタ
        public Form1()
        {
            InitializeComponent();

            this.Users = this.CreateUserList();

            // ■リストからディクショナリを作成

            // 【1-1】引数が1つ
            // Valueを指定しない場合
            // IdをKey、UserオブジェクトをValueとしたディクショナリを作成
            Dictionary<int, User> userDic1 = this.Users.ToDictionary(x => x.Id);

            // 【1-2】引数が2つ
            // IdをKeyに、NameをValueとしたディクショナリを作成
            var userDic2 = this.Users.ToDictionary(x => x.Id, x => x.Name);


            // ■ディクショナリからディクショナリを作成

            // 【2-1】引数が1つ
            // ValueはuserDic1の<Key, Value>がそのまま入ってくる
            // 1-1と同じ使い方。
            var userDic3 = userDic1.ToDictionary(x => x.Key);

            // 【2-2】引数が2つ
            // Keyを多少変更してディクショナリを作り直した例
            // 1-2と同じ使い方。
            var userDic4 = userDic1.ToDictionary(x => x.Key.ToString().PadLeft(3, '0'), x => x.Value);
        }

        #region CreateUserList:検証用のリストを作成
        private List<User> CreateUserList()
        {
            var list = new List<User>();

            for (int i = 1; i < 6; i++)
            {
                var user = new User()
                {
                    Id = i,
                    Name = "名前" + i.ToString(),
                    Birthday = "生年月日" + i.ToString(),
                    Email = "メール" + i.ToString(),
                };
                list.Add(user);
            }

            return list;
        }
        #endregion
    }
}

参考

ToDictionaryのソースコード(Reference Source)
File: System\Linq\Enumerable.cs
Project: ndp\fx\src\Core\System.Core.csproj (System.Core)
http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,97b7f242af9248ab

C#のCompareメソッド、CompareToメソッドの戻り値の覚え方。すぐ忘れる人向け

覚え方

普通の算数式のようにイメージすると、合点がいく。
「左 - 右 = 結果」の「結果」が正か負かを調べると考えるとわかりやすい。

なるほど、これは覚えやすい(´・ω・`)!

string str01 = "01";
string str05 = "05";
string str10 = "10";

// 01 - 05 = -04(負の数のとき、負の-1が返る)
// 戻り値:-1 (>= 0)
var res1 = str01.CompareTo(str05);

// 10 - 05 = 05 (正の数のとき、正の1が返る)
// 戻り値:1 (<= 0)
var res2 = str10.CompareTo(str05);

// サンプル
if (str01.CompareTo(str05) < 0)
{
    // 05が大きいとき
}
if (str10.CompareTo(str05) > 0)
{
    // 05が小さいとき
}

参考

String.CompareTo メソッド
https://msdn.microsoft.com/ja-jp/library/35f0x18w(v=vs.110).aspx

Reference Source   http://referencesource.microsoft.com/#mscorlib/system/string.cs,141ddf57a009d676


CompareToメソッドの中では、CultureInfoのCompareInfoのCompareメソッドが呼ばれています。

String.Compare メソッド
https://msdn.microsoft.com/ja-jp/library/zkcaxw5y(v=vs.110).aspx

SQL Server エラー「'=' 付近に不適切な構文があります。」

原因

使用中のSQL Serverのバージョンで使用できない構文を使用していてエラーになっていた。

具体的には+=(インクリメント演算子)はSQL Server 2008以降で使えるが、
SQL Server 2005で使おうとしていて構文エラーになっていた。

対応策

SQL Serverのバージョンを2008以上に上げる
・「@I += 1」→「@I = @I + 1」と書きかえる