LastUpdate: 2023/05/29 14:01:44

戻る

プログラミング言語入門 C#
http://school.topposystem.co.jp/CS/Index.asp

C# コーディング規約

20070918 配列系のメモ
20070920 継承コントロールを作ってみたい
20080306 イベントハンドラーの追加はどうするの?
20080307 sealed って何
20080308 Unisingディレクティブを追加にするには
20080310 フォーカス移動に伴うイベント
20080310 フォームを終了させるには
20080310 チェックボックスの値を知るには
20080310 テキストボックス系のGUI
20080310 フォームの外観あれこれ
20080311 ロストフォーカスチェックと最終チェックの実装方法の考察
20080311 文字が日付に変換できるかどうかの判定
20080311 文字が数字(UINT)に変換できるかどうかの判定
20080311 ロストフォーカスチェックと最終チェックの実装方法の考察
20080311 CompareTo の 覚え方
20080312 列挙型 enum
20080312 とにかく、DBから値を取ってくる
20080312 データセットを使って、DBから値を取ってくる
20080324 データベースデザイナを用いてみたい
20080312 String と string
20080317 アクセス修飾子
20080319 APIヘルプが作成できない
20080321 メソッドの引数について
20080321 書式文字列 {0}
20080321 GetLastError の取得の仕方
20080321 iniファイルを扱う
20080324 partial とは
20080327 中カッコ { } の改行方法を変更したい
20080331 スタートアップフォームの変更の仕方
20080403 データベースへの接続のチュートリアル
20080403 トランザクション20080409 スリープの仕方
20080409 DoEvents に相当する機能
20080409 インスタンスの破棄についての考察
20080409 イベントハンドラーの追加と削除
20080409 処理中マウスカーソルと2度押し防止について
20080410 例外

 



20070918 配列系のメモ

配列関係


20070920 継承コントロールを作ってみたい

テキストボックスや、コマンドボタンなど、標準のコントロールを拡張したコントロールを作ってみる

20070920 継承コントロールを作ってみたい


20080306 イベントハンドラーの追加はどうするの?

プロパテイをイベントタブに切り替えて、そこから、メソッド名を選ぶようだ。

つまり、イベントとメソッドを自由に結びつける事ができるみたい。

イベントアクションの所を、ダブルクリックすると、規定値のメソッド名が埋め込まれるようだ。


20080307 sealed って何

シールド と読む。これ以上継承不可なこと。Javaでいう、Finaliseの事

ms-help://MS.VSCC.v90/MS.msdnexpress.v90.ja/dv_csref/html/8e4ed5d3-10be-47db-9488-0da2008e6f3f.htm


20080308 usingディレクティブを追加にするには

必要なクラスを記述した、ドロップダウンを表示すると、良い。



下記のように追加される。

 

参考
自動コード生成
http://msdn2.microsoft.com/ja-jp/library/cdbwbc30.aspx

 


20080310 フォームを終了させるには

            this.Close();

とすれば、良い。内部で、Disposeメソッドが呼び出される。← 未検証???

また、FormClosing 、 FormClosed イベントが発生する。


20080310 チェックボックスの値を知るには

textBox1.ReadOnly = checkBox1.Checked; 

 


20080310 テキストボックス系のGUI

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            textBox1.ReadOnly = checkBox1.Checked; 
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            textBox1.Enabled = checkBox2.Checked;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            textBox1.ReadOnly = checkBox1.Checked;
            textBox1.Enabled = checkBox2.Checked;
        }
    }

入力可能なテキストボックス

表示のみのテキストボックス

無効なテキストボックス


20080310 フォームの外観あれこれ

20080310 フォームの外観あれこれ を参照


20080311 文字が日付に変換できるかどうかの判定

VB で いうところの isDate に相当するもの

            DateTime dateTime;
            if (DateTime.TryParse( inputDate.Text, out dateTime))
            {
                //変換できた時の処理
            }

20080311 文字が数字(UINT)に変換できるかどうかの判定

VB で いうところの isNumeric に相当するもの

            uint uintResult;
            if (! uint.TryParse(inputSyohinCode.Text, out uintResult)) {
                MessageBox.Show("商品コードが数字ではない");
                e.Cancel = true;
                return;
            }

 


20080311 ロストフォーカスチェックと最終チェックの実装方法の考察

20080311 ロストフォーカスチェックと最終チェックの実装方法の考察


20080311 CompareTo の 覚え方

A.CompareTo(B) とあった場合

A > B  の時は、0よりも大きな 値となる

A < B  の時は、0よりも小さな 値となる

これが、覚えにくい!

そこで、  A - B  と 覚えましょう。

3.CompareTo(1)  は  3 - 1 = 2 となり、0よりも 大きな値が返却される事になります。


20080312 列挙型 enum

http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_016/csharp_abc01.html


20080312 とにかく、DBから値を取ってくる


    class Program
    {
        static void Main(string[] args)
        {
            System.Data.OleDb.OleDbConnection cn = new System.Data.OleDb.OleDbConnection();

            //接続文字列を設定
            cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0 ; " 
                    + "Data Source=C:\\Documents and Settings\\sp0058\\My Documents\\Visual Studio 2008\\testdb1.mdb;";
            try
            {
                //DBへ接続する
                cn.Open();

                //接続状態を見る
                Console.Out.WriteLine(cn.State);


                System.Data.OleDb.OleDbCommand com
                    = new System.Data.OleDb.OleDbCommand("select * from tbl_test1",cn);

                System.Data.OleDb.OleDbDataReader reader
                    = com.ExecuteReader();

                while (reader.Read())
                {
                    Console.Out.Write(reader.GetString(0));
                    Console.Out.Write(reader.GetString(1)); 
                    Console.Out.WriteLine(reader.GetString(2));                    
                }


                //DBへの接続を閉じる
                cn.Close();


            }
            catch (Exception ex)
            {
                Console.Out.WriteLine(ex.Message);
            }

        }
    }

できた事はできたけど、readerから 値を取得するときに、GetString(0) などと、列数で指定するのは ちょっとなぁ〜

他のページを見ていたら、名前で取得する方法も載っていた。

                    Console.Out.Write(reader["key1"]);
                    Console.Out.Write(reader["data1"]);
                    Console.Out.WriteLine(reader["data2"]);                    

インデクサ?っていうの? こんな感じで取得できるようだ。

http://www.atmarkit.co.jp/fdotnet/basics/adonet02/adonet02_02.html

 


20080312 データセットを使って、DBから値を取ってくる

教則本に載っていたのをベースに作ってみる

    class Program
    {
        static void Main(string[] args)
        {

            System.Data.OleDb.OleDbConnection cn = new System.Data.OleDb.OleDbConnection();

            //接続文字列を設定
            cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0 ; "
                    + "Data Source=C:\\Documents and Settings\\sp0058\\My Documents\\Visual Studio 2008\\testdb1.mdb;";
            try
            {

                //接続状態を見る
                Console.Out.WriteLine(cn.State);

                System.Data.OleDb.OleDbDataAdapter adapter
                    = new System.Data.OleDb.OleDbDataAdapter("select * from tbl_test1", cn);

                System.Data.DataSet testDataSet = new System.Data.DataSet("test");
                adapter.Fill(testDataSet, "test");

                System.Data.DataTable testDataTable = testDataSet.Tables["test"];


                for (int i = 0; i < testDataTable.Rows.Count; i++)
                {
                    Console.Out.Write(testDataTable.Rows[i][0]);
                    Console.Out.Write(testDataTable.Rows[i][1]);
                    Console.Out.WriteLine(testDataTable.Rows[i][2]);
                }


            }
            catch (Exception ex)
            {
                Console.Out.WriteLine(ex.Message);
            }

        
        }
    }

なんと、DbConnection の Open/Close をしていない!

testDataTable.Rows[i][0] となっているのがなぁ〜。データセットとか、データテーブル とかを、もっと掘り下げてみる必要がありそうだ。

http://www.atmarkit.co.jp/fdotnet/basics/adonet_index/index.html

http://www.atmarkit.co.jp/fdotnet/basics/adonet04/adonet04_01.html


20080324 データベースデザイナを用いてみたい

http://www.atmarkit.co.jp/fdotnet/vblab/vsdbprog_01/vsdbprog_01_01.html を参考にしながら、やってみる。

20080324 データベースデザイナを用いて行ってみる1


20080312 String と string

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=33576&forum=7


20080317 アクセス修飾子

スコープの話

アクセス修飾子 説明
public アクセスの制限はありません。
protected アクセスは、クラス内、またはクラスから派生した子クラス内に制限されます。
internal アクセスは現在のアセンブリに制限されます。
protected internal アクセスは、現在のアセンブリ、またはクラスから派生した子クラス内に制限されます。
private アクセスはクラス内に制限されます。
{ } アクセスは、中カッコ内に制限されます。

.NETの名前空間と、JAVAのパッケージは異なる。

JAVAのパッケージは、アクセス制限子により、完全ガードをかける事ができるが、名前空間はクラスなどの修飾子やグルーピングには使用できてもアクセス制限ができない事である。

逆に、javaでは、JARアーカイブによるスコープ制限はできないが、.netではアセンブリによるスコープ制限が可能となっている。

規定値

種類 取りうる値    太字は規定値
名前空間内のメンバ
(クラス、enum、interface、struct)
public , internal
enum内のメンバ public
class内のメンバ
(プロパティ、メソッド)
public , internal, private , protected internal
interface内のメンバ public
struct内のメンバ public , internal, private

アクセシビリティ レベル
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/csref/html/vclrfDeclaredAccessibilityPG.asp

 

for文のindexについて

for(int i=0 ; i < 10 ; ++i )
{  ...  }

この場合の i は for文の中のみ有効である。 

参考

アクセス修飾子 - C# プログラミング ガイド | Microsoft Learn

少ない型数の名前空間を作成しないでください
http://msdn2.microsoft.com/ja-jp/library/ms182130.aspx

言語の比較

http://msdn2.microsoft.com/ja-jp/library/zwkz3536(VS.80).aspx

http://www.ne.jp/asahi/hishidama/home/tech/lang/index.html

http://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E8%A8%80%E8%AA%9E%E3%81%AE%E6%AF%94%E8%BC%83


20080319 APIヘルプが作成できない

.NETでは、Javadocのような機能が2種類用意されている。

APIヘルプとXMLドキュメントである。

APIヘルプは、VSのツールメニューから呼び出せるらしいが、自分が使っているVSでは、表示されない。

どうも、Express版ではAPIは使用できないらしい。

しかし、XMLドキュメントから NDoc というツールで、かなりイケテルドキュメントが生成できるとの事。

http://vsug.jp/tabid/63/forumid/42/threadid/2075/scope/posts/Default.aspx

ところが、NDoc、Framework2.0に正式に対応しなかったらしく、今は Sandcastle という マイクロソフトが提供している同様なソフトがあるらしい。

http://d.hatena.ne.jp/keyword/Sandcastle


20080321 メソッドの引数について

値型( = 構造体型)は、値のコピーが行われている。
参照型は、参照渡しされている。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int arg1 = 12;

            TestData testData = new TestData();
            testData.value = 500;
            string s = "aaa";

            testMethod(arg1, testData,s);

            Console.WriteLine("arg1={0}", arg1);
            Console.WriteLine("testData.value={0}", testData.value);
            Console.WriteLine("s={0}", s);

        }

        static void testMethod(int arg1, TestData testData,string s)
        {
            arg1 = 13;
            testData.value = 512;
            s = "bbb";
        }

    }

    class TestData {
        public int value;
    }

}


arg1はint型、つまり構造体型なので12のまま。
sはstring型、つまり構造体型なので"aaa"のまま。

testData.valueはクラス、つまり参照型なので512に書きかわっている。

 

参照渡しをするには… out を使う

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int arg1 = 12;

            TestData testData = new TestData();
            testData.value = 500;
            string s = "aaa";

            testMethod(out arg1, testData, out s);

            Console.WriteLine("arg1={0}", arg1);
            Console.WriteLine("testData.value={0}", testData.value);
            Console.WriteLine("s={0}", s);

        }

        static void testMethod(out int arg1, TestData testData, out string s)
        {
            arg1 = 13;
            testData.value = 512;
            s = "bbb";
        }

    }

    class TestData {
        public int value;
    }

}

outを適用すると、参照渡しになるので、引数の値を変更する事が可能となる。
C#の場合は、引数が変更される可能性がある事を、呼び元でも意識させる必要があるので、
呼び元でも、out句を宣言する事が必要である事に注意

out と ref

参照渡しをする場合には、out句の他に ref句を用いる事もできる。違いは以下の通り。

  呼び元 呼ばれた先
out 実体が指し示されていなくても良い。初期化されていなくても良い。 値を設定しなくてはならない
出力を強要する。
ref 実体が指し示されている必要あり。初期化されている必要あり。 設定は、任意

つまり、out句は、出力の為の引数である事を示す事が目的である。

もともと参照型であるクラスインスタンスをout句で呼び出した場合は、呼ばれた先で、インスタンスIDの設定/変更が強制される。インスタンスID内部のパラメタの値では無い事に注意

refは参照型オブジェクトの中のメンバを変更するのではなく、参照型オブジェクトそのものを変更するかもしれない時に用いるものである。

C# プログラマーズ リファレンス out
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/csref/html/vclrfout.asp


20080321 書式文字列 {0}

基本形

string errorString = string.Format("ERROR CODE = [{0}]", 123);

errorString は "ERROR CODE = [123]" と なる。


20080321 GetLastError の取得の仕方

取得する対象の関数に、SetLastError=true をつけておく。

        [DllImport("KERNEL32.DLL",SetLastError=true, EntryPoint = "WritePrivateProfileString")]
        private static extern uint 
            DllWritePrivateProfileString(
                string lpAppName,
                string lpKeyName,
                string lpString,
                string lpFileName);

取得する時は、GetLastError ではなく  Marshal.GetLastWin32Error() を 用いる。

http://blog.tbl.jp/2007/10/cwin32apigetlasterror.html

Win32エラーコード一覧
http://ir9.jp/prog/ayu/win32err.htm


20080321 iniファイルを扱う

習作として、iniファイルを読み書きするクラスを作成してみた。

iniファイルを扱う


20080324 partial とは

部分型定義 の事である。つまり、ひとつのクラスを、複数のファイルで別けて定義する事。

利点

http://school.topposystem.co.jp/CS/CS-23.asp


20080327 中カッコ { } の改行方法を変更したい

以下の方法でできる

既に、フォーマットされてしまっているコードを、後から再設定したい場合は、貼り付け直しをした際に、オートフォーマットが有効ならば、カット&ペーストで OK


20080331 スタートアップフォームの変更の仕方

VS2008の場合は、以下の方法しか、無いのかな〜

プロジェクトのプロパティを開く

スタートアップオブジェクトが、Program となっているので、それを、開いてみる。

Programクラスの Mainメソッドで、Form1 と指定されているのを、最初に起動させたいフォームに変更する。


20080403 データベースへの接続のチュートリアル


ms-help://MS.VSCC.v90/MS.msdnexpress.v90.ja/dv_raddata/html/4159e815-d430-4ad0-a234-e4125fcbef18.htm


20080409 スリープの仕方

処理の一時停止、スリープ sleep 

3秒停止の場合

System.Threading.Thread.Sleep(3000);


20080409 DoEvents に相当する機能

//メッセージキューに現在あるWindowsメッセージをすべて処理する
System.Windows.Forms.Application.DoEvents();

http://dobon.net/vb/dotnet/vb6/doevents.html


20080409 インスタンスの破棄についての考察

ある一定期間だけインスタンスのライフサイクルをコントロールしたいとするならば…。

using 句を用いて、コントロールすると良い。

        private void button1_Click(object sender, EventArgs e) {

            using (LifeCycleTest lifeCycle = new LifeCycleTest()) {
                #region 何らかの処理
                #endregion 
            }
        }
    class LifeCycleTest : IDisposable {
        
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public LifeCycleTest() {
            System.Console.WriteLine("LifeCycleTest コンストラクタ");
        }

        #region IDisposable メンバ

        public void Dispose() {
            System.Console.WriteLine("LifeCycleTest Dispose");
            
        }

        #endregion

        /// <summary>
        /// ディストラクタ
        /// </summary>
        ~LifeCycleTest() {
            System.Console.WriteLine("LifeCycleTest ディストラクタ");
        }

    }

 

using で スコープを抜ける時、Disposeメソッドを呼び出すカラクリになっている。つまり、System.IDisposable インターフェイス型である(インターフェイスを実装している)必要がある。
System.IDisposable インターフェイス型でない場合は、コンパイルエラーとなる

using ステートメントで使用される型は、暗黙的に 'System.IDisposable' への変換が可能でなければなりません。

上記の例では、明示的にディストラクタを実装してみたが、ディストラクタが呼び出されるのは、メモリから破棄されるタイミングである。
このタイミングは、ガベージコレクションに依存する。つまりDisposeが呼び出されても、ディストラクタが何時行われるかは制御できない。

 Disposeは、「不要となった」事をマーキングさせる為の機能と解釈するのが良いと思われる。

参考
http://www.atmarkit.co.jp/fdotnet/easyvs/easyvs03/easyvs03_06.html
http://www.atmarkit.co.jp/fdotnet/dotnettips/027dispose/dispose.html
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_011/cs2_011_03.html


20080409 イベントハンドラーの追加と削除

たとえば、ボタン1のクリックイベントが発生した場合、複数のイベントハンドラーを呼び出したいというニーズがあった時に、対応する事ができます。

    public partial class Form3 : Form {

        public Form3() {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e) {
            System.Console.WriteLine("普通のボタン1クリックイベント");
        }

        // 追加するイベントリスナー
        private void AddEvent(object sender, EventArgs e) {
            System.Console.WriteLine("追加のイベント");
        }

        private void Form3_Load(object sender, EventArgs e) {

            // ボタン1クリックイベントに、イベントリスナーを追加する
            this.button1.Click += new System.EventHandler(this.AddEvent);
        }

        private void Form3_FormClosed(object sender, FormClosedEventArgs e) {

            // ボタン1クリックイベントから、イベントリスナーを削除する
            this.button1.Click -= new System.EventHandler(this.AddEvent);

        }

    } 

イベントリスナーを追加する時は += は 理解できるんだけど、
削除する時に、 -= new … っていうのは 理解しにくい構文です。

実行すると、
    普通のボタン1クリックイベント
    追加のイベント
のように表示されます。


20080409 処理中マウスカーソルと2度押し防止について

ボタンクリック処理で処理時間がかかる際、マウスカーソルを砂時計にする…というのはよくあるニーズだが、処理が終わった際にはマウスカーソルを初期値に戻したいわけで。出口処理が複数有った時に、それぞれでマウスカーソルを初期値に戻すのは、かっこわるい。

VC++の頃は、ローカル変数のディストラクタが明示的に走る事を利用して、マウスカーソルを自動的に初期化するような便利なクラスがあったが、ガーベジコレクションする.NETで、同様な事ができないか〜と思い、考えてみた。

20080409_イベントハンドラーの追加と削除 の機能を使えば、似たような事はできるのでは…との思いから、チャレンジしてみる事にした。

が!

コマンドボタンの2度押し防止の事を合わせて検討する必要に発生したため、合わせて 検討してみる事にした。

詳細はココで  処理中マウスカーソルと2度押し防止について


20080410 例外

.NET における例外管理
http://www.microsoft.com/japan/msdn/net/bda/exceptdotnet.aspx

自分で例外を作成する時は、ApplicationException を継承すべし…最近は、推奨されてない?

http://shinshu.fm/MHz/95.83/archives/0000127004.html

1.x系の時はApplicationException を継承すべしだったそうだが、
2.x系の時は、Exceptionで良いとの事

Javaにある検査例外は、.NETには無い

既存の例外の一覧が見やすいページ
http://msdn2.microsoft.com/ja-jp/library/system.exception.aspx

 


戻る