Study / C# 検索結果

検索件数 : 61

1

こんにちは。明月です。この投稿はc#のウィンドウフォーム(window form)でスレッド(thread)を使い方、クロススレッド問題解決に関する説明です。以前の投稿でc#のスレッドに関して説明したことがあります。link - [c#] 37. スレッド(thread)を使い方、thread.sleep関数を使い方スレッドはプログラム内で並列処理することの意味です。まずウィンドウはシングルスレッドの無限ループで動いています。でも、我々がボタンのクリックイベントでループを実行するロジックを作りましょう。プログラムを実行してボタンを押下するとループが終わるまでウィンドウフォームは動きません。時間が流れたら応答なしになってプログラムが凍っている時もあります。つまり、ウィンドウはシングルスレッド状況なのでその関数のスタックに掛けると処理が終わるまで動きません。そうするとボタンを押下する時、複雑な処理をすると思えばどのように処理するでしょう?スレッドを利用すれば良いでしょう。ボタンをクリックしてコンソールに1ずつに出力してもウィンドウが凍らないことを確認できます。そうすると今回はコンソールに出力することではなく、ウィンドウのコントロールで出力するように作成しましょう。ボタンをクリックするとすぐエラーが発生します。理由はwindowで動いているスレッドとスレッドプールで動いているスレッドが同期化されてないからです。スレッド間に同期化しようと思えば、お互いにlockを設定して同期化すればよいのに、ウィンドウメッセージを動いているスレッドにlockを掛ける方法がありません。これをc#ウィンドウ開発ではクロススレッド問題と言います。これを解決する方法が各コントロールにあるinvoke関数を利用してvisitorパターン、つまりコールバック関数という方法で処理ができます。ソース上にstatic utilクラスを作成してcontrolクラスの拡張関数を作成しました。そしてスレッドプールの中でlabel1インスタンスにinvokecontrol関数を呼び出してラムダ式でコールバック関数を作成しました。ボタンをクリックするとlabelに数字が1秒単位で更新することを確認できます。ここまでc#のウィンドウフォーム(window form)でスレッド(thread)を使い方、クロススレッド問題解決に関する説明でした。ご不明なところや

Study / C#

#C#,#window,#thread

作成日付 : 2021/11/04 19:29:51       修正日付 : 2021/11/04 19:30:43

2

こんにちは。明月です。この投稿はc#のウィンドウフォーム(window form)のイベント設定する方法に関する説明です。以前の投稿でウィンドウフォームにコントルールを追加してcontrolクラスを継承してコントロールを作成する方法に関して説明しました。link - [c#] 59. ウィンドウフォーム(window form)にコントロール(control)を使い方法コントロールというのはフォームで動的に動いているオブジェクトという意味ですね。ユーザから入力を受け取るか(textbox)、マウスからクリックのアクションを受け取るか(button)、データを表示する(gridview)などの様々なコントロールがあります。このコントロールの状態が更新する時に発生する処理をイベントと言います。基本的にコントロールのイベントを受け取る方法が二つの方法があります。始めはオブジェクトの再定義(override)する方法があります。ボタンをクリックするとコンソールにclickの値が出力されます。でも、上みたいにイベントを設定することになったら基本的に提供するコントロールを使うためにはすべてのコントロールクラスを継承して再定義しなければならないですね。二つ目はeventキーワードを利用するイベント設定です。eventを利用してクリックイベントを追加する方法です。eventキーワードに関しては以前の投稿で説明したことがあるのでご参考してください。link - [c#] 25. イベント(event)キーワードを使い方二つの方法ではどの方法が良いかというと仕様別で差異があります。一応、overrideとeventキーワードを利用するイベントでどの流れで動いているかを説明します。実行順番を見ると再定義したonclick関数が呼び出されます。その後でeventキーワードのイベント関数が呼び出されます。そしてまた、onclick関数のコンソールに出力が実行します。つまり、外部クラスのイベントを発生する前には再定義したonclick関数が呼び出されるし、base.onclickを通って外部eventキーワードの関数を実行して、再定義した関数に戻ってスタックが終了します。もし、base.onclick関数をコメントしたらどうでしょう?外部に登録したeventキーワードの関数が実行されません。そしてbase.onclickの呼び出すと

Study / C#

#C#,#controlevent

作成日付 : 2021/11/02 21:18:08       修正日付 : 2021/11/02 21:18:08

3

こんにちは。明月です。この投稿はc#のウィンドウフォーム(window form)にコントロール(control)を使い方法に関する説明です。以前の投稿でwindow formを作成する方法に関して簡単に説明しました。link - [c#] 58. ウィンドウフォーム(window form)を作成する方法、そしてウィンドウメッセージとキュー一般的に我々がウィンドウプログラムを作成するとよく使うクラスはたぶんコントロール(control)オブジェクトです。このコントロールオブジェクトは基本的に.net frameworkから提供しています。実はこの基本的なコントロール(control)だけ使ってもほぼすべてのウィンドウプログラムを作成することができます。仕様により必要なコントロール(control)を開発することができますが、私の考えで多いプロジェクトが基本的に提供するコントロールだけで十分に開発ができると思います。まず、フォームにコントロールを追加する方法はデザイン画面でドラッグアンドドロップ(drag and drop)を利用して追加することがあるし、form1.designer.csページでソースを作成して追加することができます。様々な簡単なコントロールを追加する部分はやはりデザイン環境で作業することが便利ですが、デザインで追加すると精密な設定は大変な部分があります。そうならform1.designer.csで追加する方法です。私がwindowフォームでコントロールを作成する方法はいったんdesignerソース画面で使うコントロールメンバー変数とインスタンス生成、そしてname設定(これが一番重要)、text設定、そしてcontrols.addを通ってwindowフォームにコントロール設定を追加します。次はまた、デザイン`モード画面に戻ってコントロールをウィンドウフォームに合わせて配置、サイズ設定をします。そしてまた、ソースに戻って精密な設定をします。なぜ、このように複雑に作るかなと思いますが、率直にvisual studioに提供するデザインモードはすごく便利です。でも、自動設定が多すぎるので気づかなくソースが作成されてしまうことも多いです。例えば、name項目です。このname項目はwindow formで別に要らないとみえますが、実は識別ですごく重要な部分です。我々がメンバー変数を宣言してメン

Study / C#

#C#,#windowform,#control

作成日付 : 2021/10/29 19:45:43       修正日付 : 2021/10/29 19:45:43

4

こんにちは。明月です。この投稿はc#でウィンドウフォーム(window form)を作成する方法、そしてウィンドウメッセージとキューに関する説明です。c#という言語はms社で開発した言語でwindow osに環境で特化されています。つまり、c#言語で我々がよく使うウィンドウ環境でウィンドウプログラムを開発することができます。javaやその以外のpythonなどを通ってウィンドウプログラムを作れないということではありませんが、でも、ウィンドウがms社の製品なのでc#からwindow apiを使うのがもっとしやすいです。実は、c#言語を勉強することはウィンドウプログラムを作るためというのも間違ってありません。最近、ゲームエンジンでよく使うunityも基本的に使う言語もc#です。それなら簡単にウィンドウフォームを作成しましょう。visual studioを起動してプロジェクト作成します。そうするとwindow forms app項目が二つが出ます。一つはcore用だし、もう一つは.net framework用です。core用を使っても構いないですが、window formは基本的にwindow環境で実行するプログラムなのに、coreを選択する必要はありません。最近に使うwindow 10には基本的に.net frameworkがインストールされていますね。そしてプロジェクト名を入力してプロジェクト作成します。それならvisual studioに基本的にwindow formが生成されています。そのままにf5(starting debugging)を押下するとウィンドウにウィンドウプログラムが実行されていることを確認できます。実はここまでしてもウィンドウプログラムを一つ作ったことと同じ意味ですね。ここで我々がウィンドウフォームにボタンを一つ追加しましょう。visual studioの隣を見るとtoolboxがあることを確認できます。そこでbuttonを探してフォームにマウスを押下しながら引き付けます。(drag-and-drop)そうするとフォームにボタンが生成されたことを確認できます。そうするとボタンをダブルクリックしましょう。そうなるとソース画面に変わったことを確認できます。何かを知らないですが、button1_clickという関数がありますね。ここでクリックする時に動作するソースを実装するらしいです。but

Study / C#

#C#,#windowform

作成日付 : 2021/10/27 20:35:44       修正日付 : 2021/10/27 20:35:44

5

こんにちは。明月です。この投稿はc#のコーティング規約に関する説明です。まず、コーティング規約に関して簡単に説明すると、コーティング規約は我々がプログラムを作成する時に守らなければならないルールと言います。プログラムの性能と効率性とは関係がないし、複数の人とプログラムを作成する時にソースを見やすくするために決めたルールです。簡単に例で話すと、関数命名法をみると「動詞 + 名詞」の型で普通は「getdata」名で作成します。でも「dataget」という関数名を作成してもプログラムが動かないということではありません。いや、「abcdefghijklm」という関数名にしてもプログラムが動くことでは何も問題がありません。でも「getdata」という関数名を作成すると関数のソースを見なくてもこの関数は「どのデータを取得する関数だ」だと予想することができますが、変な関数名で作成すると関数名だけでどの動作するかを分かりません。それでmsにはc#をコーディングする時に、関数命名法、ソース内でスペース規則などのルールを設定して使うことでお勧めしています。これをコーディング規約と言います。link - msのコーティング標準命名ルール正規化されたクラスの名前に一行目に長く表示されないようにしましょう。つまり、含めているすべてのnamespaceを設定する必要がありません。< p="">レイアウトルール良いレイアウトルールは、コードの構文を強調して読みやすく作成することです。1. 基本コード編集ツールの設定 (4文字インデント、スペースで保存されたタブ)を使いましょう。   ショットキーはctrl + k + dです。   link - https://docs.microsoft.com/en-us/visualstudio/ide/reference/options-text-editor-csharp-formatting?view=vs-20192. 一行目には一つのステップだけ作成しましょう。3. 連続的にチェインパターンの関数宣言する時、自動にインデントができないなら、タブ間隔をインデントしましょう。(4スペース)  &

Study / C#

#C#

作成日付 : 2021/10/21 18:57:02       修正日付 : 2021/10/21 19:04:52

6

こんにちは。明月です。この投稿はc#の値の初期化及び基本データ値(default)を設定する方法、そして原始データのnull処理、?と??の使い方に関する説明です。我々がプログラムを作成すると変数の初期値を設定する場合があります。例えばintタイプのメンバー変数を作成すると初期データを-1にするか? 0にするかの悩みがある場合があります。もちろん、-1に設定するか、0に設定するかに関しては仕様により設定しなければならないですが、int a = 0;式の設定よりもっとプログラムらしいな設定がないかな?上の例をみればintタイプのdataメンバー変数にdefaultキーワードを使ってintの初期値を設定しました。コンソールに出力すると0の値が出力されますね。つまり、defaultは該当なデータタイプの初期データの値をリターンするキーワードです。原始データの場合は初期intの場合0を、floatの場合は0.0を設定します。それならここでメンバー変数の値にdefault(int)を外して出力するとどの値がリターンされるかな?同じの0の値があります。そうれならdefaultを設定する必要がないかな?正解は設定する必要がありません。基本的にメンバー変数は基本初期値が設定されます。つまり、default(int)を作成しなくてもdefault(int)値で設定することです。でも、仕様によりintの値にnullを許して設定したい場合があります。つまり、基本値が0ではなくnullをします。データタイプに?を入れたら原始データにnullを許します。そしてdefault(int?)はnullです。つまり、、基本初期値がnullになります。原始データではないクラスの場合はどうでしょう?classは基本的にnullを許すため、?を入れなくてもdefault(string)はnullの値です。そうすると原始データとclassの差異が何があるので、この差異があるかな?基本的にc#には原始データを構造体(struct)で認識しています。つまり、構造体はnullを許せません。私がstructで構造体を生成すると使い方は基本的にclassと似てますがnullを許せません。構造体でnullを許すためには?を使わなければならないです。ここでまた知りたいことがメンバー変数はdefaultを使わなくてもクラスの場合はnullになるし構造体(stru

Study / C#

#C#

作成日付 : 2021/10/21 18:54:41       修正日付 : 2021/10/21 18:55:58

7

こんにちは。明月です。この投稿はc#でのnamespaceとusing、そしてpartialの使い方に関する説明です。namespacec#では最小単位のオブジェクト(object)をクラスだと説明しました。link - [c#] 10. クラスを作成する方法(コンストラクタ、デストラクタ)我々が実行関数(main)を使ってもその関数は必ずクラスの中で含めなければならないです。つまり、関数だけには使えません。それで我々がプログラムを扱ったら様々なライブラリを連結して色々ソースを作成することになります。その場合、クラス名がすべて別々に作成することが可能かな?参考にクラスはオーバーライド(override:同じ名で別の処理)ができないです。同じ名のクラスを作成すると必ずエラーが発生します。そうすると我々がプログラムを作成する時にはそれを気を付けて作成すると思っても、オープンライブラリを連結して使う時にそのライブラリ中であるクラス名が絶対に重複されないか?可能性が十分にあります。それなら我々がライブラリを連結して使わなければならないなのにクラスが重複になって実行されません。それを避けるためにnamespaceがあります。namespaceを二つに分けてclassを生成すれば同じclass名でも生成が可能です。正解にはtest1.node名とtest2.node名のクラスなので別のクラス名です。このように別のnamespaceをユニークに指定しておいたら別のライブラリとクラス名が衝突する可能性がありません。usingでも、namespaceは重複宣言が可能です。上の例ではnamespaceをa、b、cで作成しましたが、この命名が長くなると、インスタンスを生成する時にクラス名が長くなります。それを短くするためにusingキーワードを使います。usingを使ってnamespaceを指定するとusingを書いたコードライン以降はa.b.cを書いてなくてもa.b.cのクラスを使えます。上の例では私が説明しやすくするために一つのページで説明しましたが、普通はクラス別でファイル(.cs)を作成するしnamespace別でフォルダを作成するため、usingをソースの最初のラインに作成します。そうなら最初の例みたいに同じクラスはどのように処理するかな?この場合はnodeのクラス区分ができないので、usingを使ってもクラスの前で

Study / C#

#C#

作成日付 : 2021/10/21 18:51:39       修正日付 : 2021/10/21 18:52:48

8

こんにちは。明月です。この投稿はc#でreflection機能を使い方 - attributeに関する説明です。以前の投稿までreflection機能を説明しましたが、簡単に要約するとソースにクラスの割り当てやクラス呼び出すことの静的な方法をデータなどにより動的なクラスを割り当てするか関数を呼び出しする方法です。実はc#にdynamicタイプがあるし、様々なパターンによりフレームワークを作成するかコアークラスを作成することではなければ別に使うことはありません。でも、reflection機能中でattributeによりクラス区分やメソッド呼び出す方法はすごくよく使います。link - [c#] 31. アトリビュート(attribute)を使い方c#のアトリビュート(attribute)はメタデータとしての役割だけですが、reflectionの機能と一緒に使うと単純なメタデータの機能だけではなく、プログラムを制御する機能に使えます。上の例は簡単にnode1クラスとnode2クラスのアトリビュートを取得する例です。他のreflectionの機能と別に差異がなさそうです。実際にはアトリビュートのタイプで関数の実行可否や順番を設定するところでよく使います。例えば、ウェブプロジェクトでアトリビュートを設定すれば、接続するユーザの権限により関数を実行するかどうかの検査やデータにより実行順番を設定することなどを設定することができます。上の例はnodeクラスでexecuteorderのアトリビュートが設定されている関数を取得して実行順番が設定されている順番とおりに関数を実行します。私が任意でアトリビュートにintタイプの値を入れて順番を設定しましたが、データベースやユーザから入力された値により順番を決定することになるとそれがinterpreterパターンになります。アトリビュートは上の例みたいにreflectionの動的実行のために使う場合がたくさんあります。実は単純にメタデータのためならただコメントを使う方がよいでしょう。reflectionとアトリビュートをよく使えば、様々なデザインパターンのアルゴリズムを作成することができるし、このようにフレームワークを作成することができます。ここまでc#でreflection機能を使い方 - attributeに関する説明でした。ご不明なところや間違いところがあればコメントしてく

Study / C#

#C#

作成日付 : 2021/10/20 19:29:31       修正日付 : 2021/10/20 19:29:46

9

こんにちは。明月です。この投稿はc#でreflection機能を使い方 - propertyとeventに関する説明です。以前の投稿までc#のreflectionのclassとmethod、variable(変数)に関して説明しました。link - [c#] 50. reflection機能を使い方 - classlink - [c#] 51. reflection機能を使い方 - methodlink - [c#] 52. reflection機能を使い方 - variablereflectionはクラスの構成要素に関して動的にデータを取得及び呼び出す方法です。javaにはclassの構成要素が関数とメンバー変数しかないですが、c#の場合はプロパティやイベントなどの特殊機能(?)をもっている関数があります。プロパティは関数機能と変数の機能を合わせた要素だし、イベントは関数を複数で重畳して呼び出す機能です。link - [c#] 21. c#のプロパティ(property)link - [c#] 25. イベント(event)キーワードを使い方まず、プロパティのreflectionは関数のreflectionと似ています。上の例はnodeクラスのdataプロパティのset関数とget関数を呼び出すreflectionです。プロパティがoopの規約のためにget、set関数なので、関数のreflectionと差異がありません。プロパティもprivateを設定することができるし、staticで設定することができますが、普通はpublicで設定します。でも、publicではなくても関数のreflectionみたいにbindingflags.public | bindingflags.nonpublic | bindingflags.staticのオプションで取得することができます。eventの場合は関数を重畳して一括で呼び出す方法です。上の例ではgetevent関数を通ってnodeクラスのeventを取得します。イベントにはdelegateタイプでイベントを追加しますが、delegate.createdelegateを通って関数をデリゲート(関数ポインター)タイプに変換しなければならないです。そしてevent reflectionを通ってイベントを追加します。私の場合は3回に追加しました。実はイベントはクラス内

Study / C#

#C#

作成日付 : 2021/10/19 21:02:58       修正日付 : 2021/10/19 21:02:58

10

こんにちは。明月です。この投稿はc#でreflection機能を使い方 - variableに関する説明です。以前の投稿でreflectionに関するクラスと関数を使い方に関して説明しました。link - [c#] 50. reflection機能を使い方 - classlink - [c#] 51. reflection機能を使い方 - methodreflectionというのはクラスや関数でソースにインスタンス生成(new)や関数を呼び出し(method())の普通の仕方ではなく、動的にreflection機能を利用して生成及び呼び出す方法という意味です。変数も同じ意味です。特にc#にはクラスの中で変数はオブジェクト指向プログラミング(oop)によるメンバー変数はprivateで生成することが一般的です。しかし、仕様により強制的に変数の値を変更するかユニットテスト(nunit)を実施する時にデバックの資料で使う場合があります。上の例は一般的なコーティングする方法でnodeクラスのインスタンスを生成する時、コンストラクタに10という値を入れてprint関数を通ってコンソールに出力しました。当然にmain関数にはnodeのインスタンスのメンバー変数のdataを参照することができません。コンストラクタからデータを入れること以外は値を変更するか値を取得することができなく、print関数を通って出力だけできます。上の例でtypeof(node)でnodeクラスのtype構造を取得した後にdataのメンバー変数を取得しました。そしてコンソールに出力するとメンバー変数の値が出力しました。その後、setvalueを通って値を格納してprint関数を呼び出したら変更された値が出力されました。ここで見るとreflectionを通って関数を取得する場合とすごく似ています。実は同じですね。上の例はnodeクラスにメンバー変数がありません。ただプロパティだけあります。でも、私がreflectionを通ってnodeクラスのメンバー変数を取得するとdataのbackingfieldというメンバー変数があります。つまり、プロパティでget、setだけで設定してコンパイルしたら自動にprivate変数が生成されることを確認できます。つまり、プロパティだけ作成しても内部的にはprivateメンバー変数が生成してoop規約に合わせることを

Study / C#

#C#

作成日付 : 2021/10/15 19:27:37       修正日付 : 2021/10/15 19:27:37

11

こんにちは。明月です。この投稿はc#でreflection機能を使い方 - methodに関する説明です。以前の投稿でreflectionの機能を利用してクラスのインスタンスを生成する方法に関して説明しました。link - [c#] 50. reflection機能を使い方 - classreflectionというのは簡単に説明すると、既存、ソースでnewキーワードを使ってインスタンスを生成する方法からstringの値により動的にインスタンスが生成されることということです。関数(method)も既存、ソース上で関数名を作成して呼び出す方法ではなく、クラス内で関数を探索して動的に実行するための方法ということです。上の例は既存の方法でprint関数を呼び出す方法です。上の例はreflectionで関数を探して実行する方法です。ソース上ではstringのデータを利用してprintの値で関数を呼び出します。上のgetmethods関数を利用してnodeクラスにあるすべての関数を取得しました。でも、c#にはすべてのクラスはobjectクラスを継承します。なので、objectの関数にも実行されます。それでパラメータが無くて、returnタイプがvoidということだけフィルターして実行しました。結果はa,b,cの関数が実行されました。私は例のために上みたいに作成しましたが、reflectionを利用するとユーザの入力値あるいはデータベースやファイルの値により実行できる関数を制御できます。簡単にインタープリターパターン(interpret pattern)を作成することができます。link - 作成中そしてreflectionを利用すればpublicになっている関数だけではなく、private、protectedのアクセス修飾子にもアクセスができます。上の例でprint関数はprivateで設定されていても、main関数から実行することが確認できます。我々が完璧なカプセル化でプロジェクトを作成しました。でもunitテストのために途中で関数がしっかり作動しているかをテストする場合もあります。祖の場合、reflectionを利用してtestclassを作成してクラスのunitテストをするとソースの修正なしでテストクラスを作成することも可能です。そしてstaticとパラメータがある関数にもアクセスが可能です。上の例はnodeク

Study / C#

#C#

作成日付 : 2021/10/14 18:34:21       修正日付 : 2021/10/14 18:34:54

12

こんにちは。明月です。この投稿はc#でreflection機能を使い方 - classに関する説明です。reflection機能とはインスタンスを動的で割り当てするか関数やフィールドおよび属性を動的に呼び出せる機能だという説明になっています。link - https://docs.microsoft.com/この説明は難しいですね。インスタンスを動的で割り当てするというのは我々がクラスのインスタンスを生成する時には普通はnewというキーワードを使います。クラスのインスタンスは基本的にnewを利用して生成するというのは、以前に十分に説明しました。link - [c#] 11. インスタンスう生成(new)とメモリ割り当て(stackメモリとheapメモリ)そしてヌル(null)インスタンスを生成する時、ソースにnew nodeという作成します。reflectionにはこれを静的の表現と言います。つまり、データや分岐により他のインスタンスを生成したいならifを使ってソースを作成しなければならないです。上の例をみればtypeという任意のデータを置いてnode1ならnode1のインスタンスを生成してその以外にはnode2のインスタンスを生成します。でも、ここで仕様によりnode3のクラスが生成したら? ifを分岐してインスタンス生成する区間を作ることになります。もちろん、クラスをもっと生成するとmain関数がずっと修正が必要になります。このように作成するとクラスが生成してもtype.gettypeのstring値によりインスタンス生成します。また、我々がクラスのコンストラクタをprivateで生成することができます。コンストラクタをprivateで設定をすればnewでインスタンスを生成することができません。コンストラクタが内部だけ生成することに設定したからです。代表的にシングルトンパターンがあります。link - [design pattern] 1-1. シングルトンパターン(singleton pattern)でも、reflectionを使ったらコンストラクタをprivateに設定されてもインスタンス生成が可能です。getparameters関数を使ってコンストラクタの種類を取得してlinqのwhereでパラメータがないコンストラクタを一つ取得します。取得すればinvoke関数を使ってインスタンスを生成します

Study / C#

作成日付 : 2021/10/13 18:34:13       修正日付 : 2021/10/13 18:34:13

13

こんにちは。明月です。この投稿はc#のoperator(演算子)のオーバーロードを使い方に関する説明です。c#でoperator(演算子)とは足す(+)、引く(-)の記号です。link - [c#] 6. 演算子どのプログラムを学んでも始めにみることは演算子じゃないかと思います。そしてオーバーロード(overrode)の意味はプログラムで再定義という意味です。link - [c#] 13. クラスの継承と再定義(override)する方法、overrideとnewの差異つまり、operator(演算子)オーバーロードというのは演算子を再定義という意味です。すなわち、我々が使っている足す(+)や引く(-)を単純に数字演算だけではなく、別の処理で再定義することができる意味です。上の例が演算子の再定義です。既存の定数タイプ(int)と実数タイプ(float)には足す(+)や引く(-)を入れたら四則演算になりますが、クラスには上みたいに再定義して使ったらコードステップを減らす効果があります。この演算記号はすべて記号が再定義することではありません。link - https://docs.microsoft.com/ 演算子 説明 +x, -x, !x, ~x, ++, --, true, false パラメータが一つの演算子として、再定義が可能です。ここでtrue、falseは二つを同時に定義しなければならないoperatorとしてboolタイプで暗黙的型変換で可能な再定義です。 x + y, x - y, x * y, x / y, x % y, x & y, x | y, x ^ y, x << y, x >> y, x == y, x != y, x < y, x > y, x <= y, x >= y パラメータが二つの演算子として、再定義が可能です。 x && y

Study / C#

#C#

作成日付 : 2021/10/12 18:28:42       修正日付 : 2021/10/12 18:28:42

14

こんにちは。明月です。この投稿はienumerableとienumerator、そしてyieldキーワードに関する説明です。以前に私がlinq式を説明しながらienumerableに関して簡単に説明したことがあります。link - [c#] 32. ジェネリックタイプ(generic type)を使い方ienumerableのインタフェースは繰り返しパターンと関係あるパターンですが、我々がよく使う繰り返しキーワードforeachで使っているインターフェースです。link - 作成中ienumerableのインタフェースはgetenumerator関数が定義されているし、ienumeratorタイプで返却することになっています。そしてienumeratorの場合はforeachで使っているパターンの動作インターフェースとして、現在値に関するプロパティのcurrent、ポイント移動と値が存在するかを確認する関数のmovenext、そしてポインタの位置を初期化する関数resetになっています。foeachの繰り返しキーワードはienumerableのインスタンスを継承したクラスの値を使えます。 我々が普通にlistやarrayをforeachに入れて使いますが、このクラスがienumerableのインスタンスを継承したことと同じ意味です。ienumerableのインタフェースはgetenumerator関数が定義されているし、ienumeratorのインタフェースを継承したインスタンスをリターンします。ienumeratorのインタフェースにはforeachで使うならreset関数を呼び出してポインタを初期化してforeachで次のポインタに移動する時にmovenextの関数を呼び出して、itemでデータを取得する時にはcurrentプロパティを使います。ここで少し変なコードが見えますが、movenext関数が先に呼び出してcurrentのプロパティからデータを取得します。movenextの返却値は現在の値がnullかどうかに関するチェックだし、ポイントを移動しなければならないです。currentは現在の値を取得することなのでcurrentではpos - 1で値をリターンするし、movenext関数では現在ポインタの現在のポインタに関するnullチェックでpos >= data.lengtのことで

Study / C#

#C#

作成日付 : 2021/10/11 19:49:33       修正日付 : 2021/10/11 19:50:10

15

こんにちは。明月です。この投稿はc#でnugetを使い方(外部ライブラリ)とデータベース(mariadb(mysql))を使い方、そしてトランザクション(transaction)に関する説明です。c#が言語的で利点だと思う部分は.net framework中で基本的なライブラリがすごく多く含めています。その以外にもvisual studioのideツールもすごく便利だし、同じ製品系(ms製品系)に関しても互換性がすごくいい利点があります。でも、多いライブラリを含めていると思っても、実際に使ってされるすべてのライブラリを持っていることではありません。例えば、基本的にc#ではmssqlデータベースに関する接続ライブラリを持っています。別に外部ライブラリが必要ありません。なので別の種類のデータベースのライブラリは.net frameworkでありません。つまり、c#を使ったらmssqlを使うことをお勧めすることです。でも、仕様により、あるいは様々な理由で開発言語はc#で開発してもデータベースはoracle(오라클)やmysql(mariadb)を使わなければならない場合もあります。そうなら外部ライブラリを使わなければならないですが、mariadbホームページに接続するとc#ライブラリファイルがあります。link - mariadb net-connectorsこのようにライブラリをダウンロードしてプロジェクトに連結して使ってもよいですが、このようにするとバージョン管理や配布(deploy)や他人とプロジェクトを共有する時、ライブラリ管理などの問題が発生します。そのため、プロジェクトのライブラリ管理ツールがありますが、javaにはmavenがあるみたいにc#にはnugetがあります。nugetはvisual studioがインストールされていると別途にインストールする必要はありません。プロジェクトでreferencesの項目でマウスの右クリックしてcontextメニューをみればmanage nuget項目があります。browseタブで検索すればインストールができるライブラリが表示されます。我々はmariadbを使っているのでmysql.data ライブラリをクリックしてversionを確認してinstallボタンを押下します。そうなら規約が表示されるし、acceptを押下してインストールを開始します。そして、re

Study / C#

#C#

作成日付 : 2021/10/08 18:58:57       修正日付 : 2021/10/08 19:00:07

16

こんにちは。明月です。この投稿はc#でデータベース(mssql)に接続する方法に関する説明です。我々がプログラムを作成すればデータを格納する場合が多いですが、ioを利用するファイルで格納する方法やsocketサーバを利用して他のpcやプログラムを利用して格納する方法などの様々な方法があります。でも、データを格納する方法で一番しやすいし、検索やフィルターする方法でデータベースを利用する方法があります。データベースの種類はすごく多いですが、その中でoracle(オラクル)、mssql(sql-server)、mysqlあるいはmariadbがよく使うデータベースです。その中でmssqlはms(microsoft)社で提供するデータベースだし、c#もms(microsoft)社で提供するプログラム言語なのでc#では他のデータベースよりmssqlが扱いしやすいです。扱いしやすいより別途のライブラリがなくても使えるデータベースです。まず、データベースを接続するためにはデータベースをインストールしなければならないですが、それは別途の投稿で説明します。link - 予定データベースがインストールされたら簡単なテーブルを作成してc#プログラムで検索してみましょう。上の例みたいにデータベースでテーブルを作成して簡単なデータを入力しました。このデータを利用してc#プログラムでデータを取得しましょう。上の例をみればデータベースにあるtestのテーブルのデータを読み込んでコンソールに出力しました。sqlcommandクラスのインスタンスを生成してコネクションを作ってexecutereaderの関数を実行してデータを読み込みました。そしてexecutereaderの関数のリターン値はsqldatareaderのインスタンスだし、sqldatareaderのread関数を利用してデータを読み込みました。上の例ではdeleteとinsertをしてデータを削除と追加しました。そして関数はexecutereaderの関数ではなく、executenonqueryの関数を使って実行しました。なぜならdeleteとinsertは検索の結果を取得することではなく、実行だけが重要だからです。上の方法は連結指向タイプのデータベース接続だといいます。つまり、データベースからデータを一括に取得することではなく、read()関数を通って一つ一つに取得するこ

Study / C#

#C#

作成日付 : 2021/10/07 18:39:58       修正日付 : 2021/10/07 22:27:12

17

こんにちは。明月です。この投稿はc#でネットワークソケット通信(socket)を使い方に関する説明です。プログラムとプログラム、そしてパソコンとパソコンでデータを送受信することを通信と言います。通信をもっと詳しく説明すると、伝送するパケット(データ)がパソコンのlanカードによってランケーブルに伝送します。ランケーブルに伝送したデータはdnsとルータなどを通って到達しようとpcのlanカードによって最終に目標したプログラムでパケット(データ)を読み込みます。端末と端末の間にデータを通信します。この時、我々は各端末間にデータ変換や装置間のプロトコール、規約などに関して実装してないです。この通信規約に関してはすべてos側で設定して(osi7階層)、我々はその上で差し込んで使うという意味でsocket通信という言います。link - osi参照モデルsocket通信規約は規則が決めています。 통신 규약은 규칙이 정해져 있습니다.先に通信を待つ側のpcをサーバというし、portを開いてクライアントの接続を待ちます。そして接続する側をクライアントと言うし、サーバのipとportに接続して通信が繋がります。サーバとクライアント間の通信はsend、 receiveのタイプでデータを送受信します。そして通信が終わったらclose関数で接続を切ります。この規約を利用してc#でソケット通信を作成してみましょう。先にserverを作成してwindowのtelnetプログラムを利用して接続を確認し、そして仕様に合わせてclientを作成します。上の内容はウィンドウtelnetプログラムで私が作ったサーバプログラムに接続する例を作成しました。先にプログラムを説明すればsocketクラスでサーバのsocketサーバのインスタンスを生成しました。bind関数を使って待機ポートを設定します。listenで同時接続待機設定をしてaccept関数を通ってクライアントの接続を待機します。プログラム上ではaccept関数が呼び出したらclient接続が発生する時までプロセスが止まることになります。そしてtelnetプログラムで接続をすることになればaccept関数を通ってクライアントsocketインスタンスをリターンするし、sendとreceive関数を通ってサーバとクライアントからお互いにメッセージを送受信することができます。上の例は私が

Study / C#

#C#

作成日付 : 2021/10/06 19:06:25       修正日付 : 2021/10/06 20:07:44

18

こんにちは。明月です。この投稿はc#でファイル(fileinfo)とディレクトリ(directoryinfo)を扱いに関する説明です。以前の投稿でioを通ってファイルを作成して読み込む方法に関して説明しました。link - [c#] 42. ファイルを扱い(io)とファイルメタデータ(fileinfo)を使い方今度はファイルを作成して読み込みより、ディレクトリとファイルのメタデータを利用してディレクトリとファイルに関する情報を取得して探索する方法に関して説明します。fileinfoクラスはファイルに関するメタデータ、つまり、ファイルのパス、サイズ、作成日時、修正日時に関する情報があります。ディレクトリは実際にバイナリデータで存在することではなく、osで管理するメタデータです。fileinfoとみたいにdirectoryinfoがありますが、ディレクトリ(フォルダ)に関する情報があります。ファイルのメタファイルみたいにディレクトリのメタ情報を取得することができます。directoryinfoにはfileinfoと違い、ディレクトリを追加、削除があります。ファイル生成は当該なファイルに関するバイナリデータが必要ですが、ディレクトリの場合はメタデータ追加、削除だけで扱えるからです。ディレクトリが追加されました。ディレクトリが削除されました。そしてfileinfoとdirectoryinfoの場合はインスタンスを生成して使わなければならないですが、毎度、メタデータを使うためにインスタンスを生成することには気になります。それでstaticクラスでもメタデータを取得することができます。existsの関数はfileinfoとdirectoryinfoにもある関数ですが、fileとdirectoryのstaticクラスにもメタデータを使えます。このfileとdirectoryクラスで単純にファイルとディレクトリのメタ情報を取得するクラスですが、探索アルゴリズムを利用して作成すれば簡単なファイル探索プログラムを作成することができます。上の例でディレクトリからサブディレクトリを呼び出す時にはディレクトリ探索する再帰関数を通ってサブディレクトリとサブファイルを探索します。再帰関数というのはstack interruptが掛ける作業なので、性能が遅くなるし、overflow可能性もあるので、効率性が悪いですが、ソースがすごく見や

Study / C#

#C#

作成日付 : 2021/10/05 19:29:34       修正日付 : 2021/10/05 19:29:34

19

こんにちは。明月です。この投稿はc#でストリーム(stream)とバイナリ(byte[])、エンコード(encoding)、そしてusingを使い方とidisposableインターフェースに関する説明です。以前の投稿でファイルを扱い(io)に関して説明しました。link - [c#] 42. ファイルを扱い(io)とファイルメタデータ(fileinfo)を使い方ここでstringデータをファイルに作成する時、encodingを使ってbyte[]配列に変換してファイルを作成するし、ファイルの内容を読み込む時にはbyte[]配列で読み込んでencodingを使ってstringに変換してコンソールに出力することまで例で説明しました。我々がファイルを読み込んで作成する時、filestreamというクラスを使ってファイルを作成するし読み込みました。まず、streamに関する説明ですが、ストリームとは一連のデータ配列という意味です。つまり、一つのデータ値では意味がなく、データの集合あるいは配列が一つのデータとして意味になるという意味です。我々がstringのデータをbyteに変換したので、utf-8の変換により英語文字の一つが一つの値で配列に格納されていますが、もし英語ではなく日本語ならどのぐらいのバイトになるでしょう?上の例で最後の0x2e(46)はasciiコードのピリオドです。その以外の15バイトは日本語です。つまり、ひらがなの一文字で3バイトのサイズを持っています。この「こ」になるデータは「e3 81 93」ですが、ここで一つのbyteは値は意味がありません。データの意味を持つためには3byteが合わせて、stringに「こ」というデータに認識することです。これがストリームということです。一つのデータを表現するためには一連の値を配列で表すことです。ここで説明しやすくするためにstringのデータで説明しましたが、プログラムでは使ってるリソースはイメージや動画などのデータのファイルなどがあります。そのデータはすべてバイトになっています。つまり、このデータは一つのbyteの値では意味がありませんが、byteの値が一連の配列になるとイメージや動画になることです。これをストリームと言います。例えば、我々がイメージプログラムでイメージをモニターに出力するため、約束したbyteの集合(規約)、データストリームが必要という

Study / C#

#C#

作成日付 : 2021/10/04 18:33:04       修正日付 : 2021/10/04 18:34:18

20

こんにちは。明月です。この投稿はc#でファイルを扱い(io)とファイルメタデータ(fileinfo)を使い方に関する説明です。プログラムで使う代表的な装置リソースならファイル扱い(ファイルで書込、読取、io)と通信ソケット(socket)があります。このファイル扱いは英語の略語でioといいますが、ioはinput ouputで入出力という意味です。入出力装置ならマウス、キーボード、モニターなどがありますが、プログラムでioといいならファイルを扱うリソースだと思えば良いです。我々がプログラムを使う時にプログラムを終了すればメモリに格納したデータはすべてなくなります。そのために、プログラムでデータを保管する方法の一つでファイルで格納する方法があります。ファイルはbyteタイプで構成されているし、プログラムではunsigned char(byte)で構成します。私はdドライブでworkというフォルダでtest.txtというファイルを作成しました。内容はhello worldで正確にスペースまで11バイトを生成します。結果をみればファイルサイズが11バイトで生成されたことを確認できます。ファイルをtxtファイルで作成し、stringデータをencodingを通ってbyteタイプに変換しました。そのため、メモ帳で該当のファイルを開くとhello worldの内容が作成されたことを確認できます。そして、最終的にリソースを使った後にはclose関数で閉めなければならないです。今回はファイルのデータを読み込んでコンソールに表示しましょう。上はファイルを読み取ってコンソール出力する例です。ファイルメタデータでファイルの情報を読み取ってファイルサイズ程にbyte配列を生成します。そしてstreamで読み取ってstringに変換しました。変換した内容をまたコンソールに表示するとhello worldが表示されます。ここのencodingとバイナリ(byte[])に関しては別の投稿で詳細に説明します。先、filestreamに関して始めのパラメータは対象ファイルのパス、ファイルモード、ファイルアクセス権限設定でストリームを生成します。ファイルモードではcreate、open、write、createnew、appendを使ったらcreateはファイルを生成する(既存ファイルがあれば上書き)、createnewもファイル生成します

Study / C#

#C#

作成日付 : 2021/10/01 20:10:21       修正日付 : 2021/10/04 18:33:35

21

こんにちは。明月です。この投稿はtaskクラスとasync、awaitを使い方に関する説明です。以前の投稿でthreadに関して説明したことがあります。link - [c#] 37. スレッド(thread)を使い方、thread.sleep関数を使い方スレッドとは並列処理だということを何度も説明したので、この投稿では省略します。threadを生成する時にシステムのリソースを使って逆にthreadが多すぎるならシステムの性能が落ちます。そのためスレッドプールに生成してスレッドの個数制限、スレッドのリソースを再活用してシステムの性能を改善することができます。でも、スレッドプールはスレッドのステータスを制御することができないので、スレッドが終了する時まで待つ(join)機能を実装しなければならない不便があります。taskはthreadpool中で動くスレッドだし、threadみたいに簡単に生成してjoin機能まで使える機能があります。上の結果をみれば先にthreadpoolで設定したスレッド制限設定がtaskで宣言したスレッドにも影響されることを確認できます。つまり、実装はthreadみたいに簡単に使えますが、内容はthreadpoolで動くことを確認できます。そしてthreadpoolと違い、return値を受け取ることができて1から5まで足すと15、スレッドが5個なので総合の75の結果が出ることを確認できます。lockを使えなくても各スレッドで結果の値を受け取ってメインプロセスでスレッドの値を受け取って使えます。そしてtaskの別の機能はasync、awaitキーワードと密接な関係があります。始めの例と結果は同じですが、taskをもっと扱いやすく実装されています。asyncが宣言された関数でtaskを生成して実行し、awaitでスレッドが終了するまで待機します。そして結果をリターンするならmainプロセスで結果を合算して結果が出ることを確認できます。ここまでtaskとasync、awaitの基本構造です。taskでcontinuewithの関数を提供しますが、これは各スレッドが終了すれば続けて処理するラムダ処理です。状況により他のtaskスレッドを付けることもできるし、様々な実行を連結して実行できる関数です。taskは.net framework 4.0から追加された機能なので、もし以前のプレームワークな

Study / C#

#C#

作成日付 : 2021/10/01 18:59:14       修正日付 : 2021/10/01 18:59:14

22

こんにちは。明月です。この投稿はc#でlinqを利用した並列処理(parallel)を使い方に関する説明です。以前の投稿で私がthreadに関して説明したことがあります。link - [c#] 37. スレッド(thread)を使い方、thread.sleep関数を使い方スレッドというのはプログラム内でいろんな処理を同時に処理、つまり、同時に処理してシステムの性能を向上させる機能です。でも、このスレッドは個数が無限的に増やすこともできないし、どのぐらいにスレッドが多くなると性能低下になるため、個数管理するthreadpoolが存在します。しかし、このthreadpoolはjoin機能が無くて、eventwaithandleクラスで同期化する機能を別に作成しなければならない不便なこともあります。linq式ではこの問題を解決する並列処理を作成できます。上の例をみればnodeクラスのインスタンスをlistに格納して、linq式のasparallel関数を呼び出すことなら並列処理になります。withdegreeofparallelismの関数を通ってparallelのスレッドの最大個数を設定してforallを通って実行します。forallはラムダ式で設定してパラメータはlistに設定されたnodeインスタンスを取得して実行します。ここまで見るとthreadとthreadpoolの欠点がなくなる機能ではないかと思います。parallel機能をlistだけ付けて使うことではなく、staticタイプのクラスで独立的に使うことができます。parallelクラスの並列処理は基本の形はfor関数です。意味はforの初期式、条件式、増減式をparallelで設定することです。つまり、forを並列に処理することです。parallelのforeachはforeach文を並列に処理する関数です。形式はlistタイプのデータを始めのパラメータに入れて、ラムダ式で各データを取得して並列処理になります。上のれ例は別に関係ないラムダ式を並列処理にしました。invoke関数のパラメータはparamsの処理なので可変的にラムダ式を入れられます。この投稿を作成しながら思いましたが、linq式のasparallel()の関数は自分もよく使える関数です。parallelクラスは別に使ったらいい利点がなさそうです。実は私も投稿を書く前には単純にaspa

Study / C#

#C#,#Socket

作成日付 : 2020/05/13 17:37:13       修正日付 : 2021/09/29 19:29:03

23

こんにちは。明月です。この投稿はc#のlockキーワードとdeadlock(デッドロック)に関する説明です。以前の投稿でスレッドに関して説明しました。link - [c#] 37. スレッド(thread)を使い方、thread.sleep関数を使い方スレッドとはプロセスの中で同時にいろんな処理を実行するための並列処理ということに説明しました。それならこの並列処理を処理する時に、一つのインスタンスや変数に値を処理するとどのようになるかな?上の結果をみると0から10まで足すスレッドを10回に実行しました。なので、0から10まで足すと55だし、10回に実行したので予想する結果の値は550が出力することが正常です。でも結果は550ではなく481ですね。望んだ結果が出ませんでした。理由はsumに値を足す時、sumの値が0の場合、始めのスレッドで1を足して1になるし、二つ目のスレッドで足す時に、1を足して2がなると予想します。でも、threadというのは並列処理なので、始めのスレッドで0から1を足す時、二つ目のスレッドで1から2になることが確かではありません。つまり、始めから0から1を足す時、二つ目のスレッドで1を足す時、まだsumの値が始めのスレッドで1になる前なので、sumの値が0の可能性があります。改めて説明すると、始めスレッド、二つ目のスレッドで0から1を足すことになります。そのように重なる処理が多くなるとsumの値が550まで届かないことになります。スレッドは少し早い処理のため、並列処理をしますが、予想する値が出ないなら意味がありません。しかし、スレッド、このすべての並列処理でsumに足す処理だけスレッドをすべて同期化したらこの問題が解決になります。クラスインスタンスにlockを掛けたらlock掛けた領域を使ったら他のlockを掛けるところでlockを通過することを待つことになります。つまり、並列処理の始めのスレッドでlock(node)を通過することになると二つ目のスレッドでの始めのスレッドのlock(node)のスタック領域が終了するまで待機することになります。そうなら始めのスレッドのlock(node)でスタックが終了になると二つ目のスレッドのlock(node)が通過して三つ目のスレッドのlock(node)が待機することになります。その順番とおりにlock(node)領域を通過することになるので

Study / C#

#C#

作成日付 : 2019/07/24 00:57:35       修正日付 : 2021/09/28 19:17:28

24

こんにちは。明月です。この投稿はc#のthreadpoolの使い方に関する説明です。以前の投稿でthreadに関して説明しました。link - [c#] 37. スレッド(thread)を使い方、thread.sleep関数を使い方threadとはプログラム内で並列処理のための機能です。でも、このthreadは個数を制御することができないと逆にプログラムの性能が落ちるということも説明しました。そのため、thread個数を管理することも作成しなければならないですが、.net frameworkにはこのthreadの個数を管理する機能があり、それがthreadpoolです。上の例をみれば私がthreadpoolクラスを利用してスレッドを総5個生成します。でも、threadpoolには同時に実行するスレッド個数は0個から最大に2個まで生成されるように設定しました。つまり、threadを無制限に生成して実行することではなく、pool中で総量を設定してその以上は待機状況に待ちます。つまり、結果を見ても、aとbは同時に実行されますが、cからはbが終了された状況で実行されることを確認でいます。threadを最大に2個を実行しますが、その以上は実行されない設定でthreadpoolを管理します。threadpoolにはthreadの生成を管理することになります。でも、このthreadpoolはjoin関数がないので、threadのすべてが終了する時まで待つ関数がありません。上の例はthreadpooljoinという関数を作成してthreadpoolで使えるスレッド個数を確認してスレッドを使える最大量と同じなら無限ループが終了することでjoin関数を作成しました。簡単なプログラムなら上みたいにthreadpoolを制御することができます。問題は大きいプログラムならthreadpoolクラスの特性がstaticなのでどのところで使っているか確認することが難しいです。ですから設計しているところでthreadpoolの使いが終了しました。と思っても、ライブラリや他のクラスでthreadpoolを使うと思えば、待機状況の個数でjoinをコントロールすると予想できないバグが発生する可能性があります。それでtaskで使えるeventwaithandleを利用すれば部分的にthreadpoolを制御することができます。listをローカル

Study / C#

#C#

作成日付 : 2019/07/23 00:05:40       修正日付 : 2021/09/27 19:33:26

25

こんにちは。明月です。この投稿はc#でスレッド(thread)を使い方、thread.sleep関数を使い方に関する説明です。我々がプログラムを作成して実行するとソースの順番とおりに実行されることが基本流れです。これがプロセスということにします。つまり、プログラムが実行して終了するまでは一つのプロセスが実行することです。上の例は0から9までの繰り返しを2回実行します。同然にa =の出力が先に実行して終了すると、b =の出力が次に実行します。これが一つのプロセスです。でも、仕様によりこの二つのfor文を並列で同時に実行したい時があります。上の例をみれば始めのスレッドと2つ目のスレッドが同時に実行してコンソールに無作為で出力されることを確認できます。つまり、上の例は一つのプロセスで2つのスレッドが実行したことです。3つの並列処理が実行されることです。例を見れは"press any key..."が先に出力されることを確認できますが、これはスレッドを実行することに少しディレイが発生したのでプロセス処理が先に出力されてしまうことです。スレッドを使う方法はthreadクラスのインスタンスを生成して、コンストラクタのパラメータは返却値とパラメータがないデリゲートで受け取ります。それでこのthread関数には変数を渡せないので、上のラムダ式を使ってクロージャ(closure)機能を利用して変数を渡す方法をよく使います。それで、上の例をみればthreadを使ってfor文で値を足したが、結果は0が出力されました。理由はスレッドが終了する時まで待たなくて、プロセスが先に実行されるからです。つまり、コンソールが出力される時にはsumの変数の値が0からです。並列で実行されるのでコンソールが出力された後でsumの変数が変わりそうですね。並列処理をすれば性能は速くなるけど、プロセスでスレッドの値をしっかり受け取ることができないと意味がありません。thread1変数でjoin関数を使ったらプロセスでスレッドが終了する時まで待ってる役割します。つまり、何個のスレッドを使ったらjoin関数を使ってプロセスと同期化するとプログラムを早く処理することができます。また、仕様によりthreadをわざと処理を遅くなることもできます。thread.sleep()関数を利用してスレッドを1秒間に停止します。sleep関数ではミリ秒単

Study / C#

#C#

作成日付 : 2019/07/22 23:45:05       修正日付 : 2021/09/24 20:40:58

26

こんにちは。明月です。この投稿はc#の拡張メソッドを使い方に関する説明です。以前の投稿でc#のメソッド(関数)を使い方に関して説明したことがあります。link - [c#] 9. 関数(method)とオーバーロード、再帰呼び出し関数というのはクラス内でデータを変更、処理する機能という文法です。クラスを作成して関数を作って、クラスの外部から呼び出すことに関してはよく知っています。でも、我々がプロジェクト内で作成したクラスではなく、.net frameworkで提供するクラスや外部ライブラリから取得するクラスに関して関数を追加したい場合はどうしよう。上の例は基本的に関数生成と使う方法に関することです。でも、もっとしやすくするためにconverttointfromstring関数がstringクラスの関数みたいに設定したいです。始めの例と差異は拡張関数をstatic classに関数を生成しなければならないです。staticが付けたらプログラムが起動する時、一括的に読み込みますが、その時に既存のstringクラスに関数を追加する役割をするらしいです。拡張関数はstaticで生成すること、始めのパラメータにthisを付けて該当のクラスの拡張関数になります。使用方法はstringでの関数みたいに使えます。visual studioのインテリジェンス(自動完成機能)にも関数があるみたいに制御になります。そして拡張関数で設定しても既存方法みたいに一般関数を呼び出すことにも使うこともできます。一般プロジェクトで処理機能だけある関数の場合、普通はutilやcommon、defineのクラスを作成して管理します。その方法が悪いことではないですが、このみたいに拡張関数で設定して置いたら可読性やソース整理することにすごく良いと思います。ここまでc#の拡張メソッドを使い方に関する説明でした。ご不明なところや間違いところがあればコメントしてください。

Study / C#

#C#

作成日付 : 2019/07/22 23:30:17       修正日付 : 2021/09/23 18:08:59

27

こんにちは。明月です。この投稿はc#で使う文字列クラス、stringとstringbuilderを使い方に関する説明です。プログラム上で使う原始データタイプは整数と実数タイプが多いですが、文字列はstringタイプで一つです。正確にはstringタイプは原始データタイプではなく、charの配列タイプになっているクラスタイプです。つまり、文字はasciiコートになっている整数タイプでそのデータタイプはcharです。改めて説明するとstringはcharの配列タイプで定義しているし、プログラム内ではstringタイプにデータを格納すると文字列で出力されます。上の例をみればstringタイプをchar[]配列タイプに変換になり、char[]配列タイプがstringタイプに変換することができることを確認でいます。link - アスキーコードここまで整理すると、stringはchar[]の配列タイプになっているし、その整数の値はアスキーコードになっていることに説明しました。ここで詳しく考えることはcharのデータサイズは1byteで2^8になっているし、その値の範囲は0~255(unsigned char)になっています。つまり、サイズが256ですが、世界のすべての文字を256のサイズで表現できません。日本語だけ見ても漢字が256個以上にありますが、そのため、文字列エンコードのutf-8があります。実はこのエンコードタイプに関しても内容が複雑だし、説明する部分が多いですが、今の標準のエンコードタイプはutf-8で統一になっているし、今はほぼエンコードタイプがutf-8だと思えば良いです。このutf-8のエンコードタイプは可変長さ文字列で最小1byteから4byteまで使って文字列を表現します。つまり、2^32になるので、役42億個の文字を表現できます。詳細な部分はbyteとエンコード部分で詳細に説明します。また、stringの説明に戻って、c#でstringのデータ構成はchar[]配列だし、構造はクラスタイプになっています。stringクラスには文字列を扱うための関数があります。isnullorempty、isnullorwhitespacestringはクラスなので、nullがあります。なのでnullの値は比較演算子で値の可否を確認できますが、nullではない文字列がないstringもあります。文字列関係の関数

Study / C#

#C#

作成日付 : 2019/07/22 23:15:42       修正日付 : 2021/09/22 18:08:53

28

こんにちは。明月です。この投稿は最上位クラス(object クラス)に関する説明です。c#にはオブジェクトの最小単位がクラスになっています。link - [c#] 10. クラスを作成する方法(コンストラクタ、デストラクタ)そのクラスは基本的にobjectのクラスを継承することになっています。link - [c#] 13. クラスの継承と再定義(override)する方法、overrideとnewの差異その意味はクラスの隣に継承する定義をしなくてもobjectクラスを継承します。つまり、c#に存在するすべてのクラスはobjectクラスを継承します。objectクラスの基本構成は下記通りです。基本的にstaticが付けてないequals関数は比較(クラスの中でメンバー変数のデータではなく、インスタンスが同じかを比較)関数、gethashcode関数はポインタアドレスをhashデータで変換した値、gettypeはクラスのデータタイプ、tostringはクラスをstringタイプに表す関数、memberwisecloneの関数はデザインパターンのプロトタイプのクラスインスタンスコピー(ポインタコピーではなく、クラスのデータがすべて複製)があります。つまり、すべてのクラスは上の関数を基本的に継承して使えます。上の例をみればprogramクラスはobjectクラスを明示的に継承してないです。でも、objectの関数を使えますね。つまり、明示的に継承することを実装しなくても、クラスは基本的にobjectクラスを継承することを確認できます。そしてequals関数とgethashcode関数、tostring関数はvirtualキーワードが付けているので再定義も可能です。上の例ををみればequals関数とgethashcode関数、tostring関数を再定義します。なのでgethashcodeの関数は常にインスタンスポインタアドレスではない可能性もあります。参考にstringクラスのgethashcodeはポインタアドレスではなく、リテラル値です。stringに関しては他の投稿で詳細に説明します。objectのクラスは最上位クラスになるので、変数宣言する時、どのインスタンスでも変数のデータタイプに設定することができます。objectクラスにはprintという関数がないので、エラーが発生します。dynamicキーワードが

Study / C#

#C#

作成日付 : 2019/07/20 02:27:23       修正日付 : 2021/09/21 19:47:40

29

こんにちは。明月です。この投稿は匿名形式(anonymous types)を使い方に関する説明です。クラスはc#でプログラムを作成するところで最小単位です。クラスの基本構造はメンバー変数と関数があり、その以外にプロパティ、デリゲート、イベント、インデクスがあります。link - [c#] 10. クラスを作成する方法(コンストラクタ、デストラクタ)そして我々が作成したクラスをメモリにインスタンス生成するためにnewというキーワードを使って生成することになります。クラスで一番重要なことはメンバー変数です。プロパティはメンバー変数に値を格納するための関数だし、デリゲートやイベント、インデクサーなども関数の役割について区分するための関数です。関数というのはプログラムを実装するための実行処理だけで、クラスのデータを格納するしクラスのサイズを決定するのは結局メンバー変数です。でも、その使い目的によりクラスをすべて作成することにはソースがすごく複雑になる可能性もあります。簡単の例として、単一目的によりデータを渡すためのクラスならそれをためクラスを作成することは無駄なこともあります。改めて説明すると、データを関数のパラメータにより渡す時、原始データだけでパラメータを作成するとパラメータが多くなりますが、パラメータのクラスを作成して渡すとソースが簡単になります。上の例をみれば、始めの関数の場合はパラメータをただ原始データタイプで受け取ります。簡単な例なのでパラメータが4個ですが、仕様によりこのパラメータが10個、20個になる可能性もあります。実際にそのように作成するとパラメータが多すぎて可読性が悪くなります。なので、普通はパラメータのデータのクラスを作成して、クラスからパラメータのデータを受け取りますが、利点はソースが読みやすくなります。でも、この問題は大きいプロジェクトだと思えば各関数のためパラメータのクラスを作成することはソースコードがすごく多くなります。それでこのように一回性のインスタンスのための匿名形式のクラスがあります。上の例でprint関数のパラメータによりデータインスタンスを渡すために、newキーワードを使ってインスタンスを生成しましたが、クラス名はありません。インスタンスの変数タイプはvarタイプで設定して、print関数からはvarタイプの変数名を使えないので、dynamicキーワードでパラメータを受け

Study / C#

#C#

作成日付 : 2019/07/20 02:22:03       修正日付 : 2021/09/20 20:38:42

30

こんにちは。明月です。この投稿はc#のジェネリックタイプ(generic type)を使い方に関する説明です。我々がリスト(list)やディクショナリ(dictionary)を使う時、どのデータタイプをリスト中で使うのかを括弧で設定します。もし、設定したデータを使わなかったらエラーが発生します。このようにどのデータタイプを使うのかを設定することがジェネリック(generic)です。つまり、クラスやメソッド中ではデータタイプを設定せず、インスタンスを生成する位置でデータタイプを設定して使う方法という意味です。上の例は簡単な連結リストのアルゴリズムです。実は連結リストのアルゴリズムは凄く簡単なアルゴリズムですが、foreachでデータを出力するためにインラインクラスのpointerを作りました。その理由で少し複雑になりました。上の例のlistクラスはintタイプだけ使えます。add関数のパラメータとnodeクラスのdataのタイプをintタイプに設定したのでintだけ使えます。しかし、状況によりintタイプではなくstringタイプのリストも作りたいです。現在の状況では上のクラスでadd関数とnodeクラスのデータタイプだけ変更してコピペするべきですね。そしてc#.net frameworkで提供するクラスや原始データではなければ、使いたい時たびに作成しなければならないです。でも、我々は実際のリスト(list)クラスを使う時にはそのように使いません。括弧(<>)を使ってデータタイプを設定して使います。ジェネリックはデータタイプが設定されてないのでtという任意の文字で置換します。つまり、インスタンスを生成する場所でintやstringで設定すればtという文字が全部intやstringタイプで変更すると思えば良いです。そうことでデータタイプによりリストコードを作成する必要せずに、ジェネリックを使えばどのタイプでも対応ができるという意味です。ジェネリックは基本的にクラスで宣言する方法があるし、メソッドだけ使う方法もあります。メソッドジェネリックは関数名の隣に設定します。上の例では関数を呼び出す時に括弧(<>)を使いますが、実際にはパラメータにstring値を入れたら自動にジェネリックが設定されます。なので関数ジェネリックを使う時は呼び出すときにジェネリックを設

Study / C#

#C#

作成日付 : 2019/07/18 22:50:16       修正日付 : 2021/09/20 20:11:14

31

こんにちは。明月です。この投稿はc#でアトリビュート(attribute)を使い方に関する説明です。c#でのアトリビュート(attribute)とはクラスやメソッドのメタデータを記録するデータです。ここでメタデータとは例えば、イメージファイルを考えるとイメージファイルはバイナリデータになっています。もちろん、このバイナリデータのはイメージに関する情報がありますが、ファイル名や拡張名などの関するデータはありません。つまり、このデータはウィンドウosのファイルに関するメタデータです。改めて説明すると、クラスやメソッドに関する区分するための表示データだと思えば良いです。上のobsoleteのアトリビュートは関数やクラスをもう使わない時、エラーを発生することです。始めのパラメータはエラーの時のメッセージです。上の結果のイメージをみればエラーメッセージがnot usedだと表示されます。その後でtrueを設定すればビルドする時にエラーが発生することだし、falseを設定すれば関数やクラスを使えますが、visual studioからの警告メッセージが発生します。アトリビュートは上の例みたいに実際のプログラム実行では影響になることではなく、プログラムのビルドやデバッグする時のメッセージ、リフレクション(reflection)でクラスやメソッドの一括管理する役で使います。リフレクション(reflection)でアトリビュートを使う方法はリフレクションを説明する時に詳細に説明します。まず、c# .netフレームワークで基本的に提供するアトリビュートは下記通りです。 アトリビュート 説明 clscompliant アセンブリのすべてのタイプをclsに合わせて使う。 obsolete 使わない要素だと表示する。 conditional プリプロセッサ識別子によって実行する

Study / C#

#C#

作成日付 : 2019/07/18 20:22:16       修正日付 : 2021/09/17 17:18:09

32

こんにちは。明月です。この投稿はc#のlinq関数式を使う方法に関する説明です。以前の投稿でlinq式に関して簡単な説明とlinqクエリ式に関して説明したことがあります。link - [c#] 28. リスト(list)とディクショナリ(dictionary)、そしてlinq式を使い方link - [c#] 29. linqクエリ式を使い方linq式に関してはプログラム内のオブジェクト(object)を効果的にフィルター、建さんしてデータを分類する文法です。クエリ式の場合はsqlクエリみたいに作成してデータを分類する方法です。クエリ式の利点はsqlクエリ式に慣れている方にはこの文法が慣れしやすいですが、少しプログラム文法と違和感があるし、途中でデバッグ状況を確認することが難しいので使うことでお勧めではありません。それでlinq式にはプログラム関数と同じlinq関数式があります。上のソースではクエリ式のfrom node in list where node.data > 5 select node.data;をlist.where(x => x.data > 5).select(x => x.data);で作成しました。ここでwhere関数とselect関数の中ではラムダ式を使ってフィルターと検索条件を生成しました。そしてwhere関数の返却値とselect関数の返却値はienumerableタイプなので、関数を連結するみたいにチェインパターンで生成することができます。つまり、上みたいにチェインパターンではなく、一行目ずつ作成することもできます。(参考、selectの場合はreturn値によりジェネリックタイプが変わるので注意)基本的にlinq関数式の場合はwhereとselectをよく使いますが、仕様により、joinと整列、グループ別に分離することもできます。first, firstordefault, single, singleordefault, last, lastordefaultこの関数はリストの結果を一つの結果に受け取る場合に使います。最終の返却値はlistではなく、listのジェネリックタイプにより結果を返却します。first、lastの場合はリストから始めの値と最後のの値を返却する関数式です。でもデータがなければexception

Study / C#

#C#

作成日付 : 2019/07/17 23:06:42       修正日付 : 2021/09/15 19:30:49

33

こんにちは。明月です。この投稿はc#のlinqクエリ式を使い方に関する説明です。以前の投稿でlinq式に関して簡単に説明したことがあります。link - [c#] 28. リスト(list)とディクショナリ(dictionary)、そしてlinq式を使い方また、簡単に説明するとlinqとはプログラム上で設定されたオブジェクトの集合、つまりリスト(list)やディクショナリ(dictionary)で設定されたデータを効果的に分類及び検索するためのc#のプログラム文法です。linqを作成する方法はクエリ式と関数式がありますが、その中でクエリ式はデータベースで使うsqlクエリ式と似ている方法です。基本的に使う方法はfrom in where selectです。まず、from inに関して説明するとinの後の変数は検索しようと思うリストの変数です。そしてforeachの繰り返し文みたいに一つのオブジェクトに置換することがfromの後の変数です。つまり、foreach(node node in list)がfrom node in listと同じ意味になります。whereは繰り返し文の中で条件を作ることでnode.data > 5はif(node.data > 5)と同じ意味です。selectはreturnされた結果により最終のfilterlistのデータタイプが決められます。select nodeをしたらienumerable<node>のタイプになりますが、上の例ではnode.dataをしたのでienumerable<int>タイプで生成されます。ここで参考にienumerableのインタフェースはlistの親インタフェースです。つまり、listみたいに使えるインタフェースですが、正確にはイテレータパターン(iterator pattern)のインタフェースです。つまり、listと似てますが、addやremoveみたいにデータを追加、削除をできなく、foreachでデータを取得することしかできないです。参考でlinqで抽出した結果にデータを追加、削除するためにはtolist()関数でlistタイプにキャストして使ったら良いです。また、クエリ式に戻って、実務プログラムを開発するとfrom where selectが一番よく使います

Study / C#

#C#

作成日付 : 2019/07/17 20:57:00       修正日付 : 2021/09/14 20:56:04

34

こんにちは。明月です。この投稿はc#のリスト(list)とディクショナリ(dictionary)、そしてlinq式を使い方に関する説明です。以前の投稿で配列とオブジェクト指向プログラミング(oop)に関して説明したことがあります。에 대해서 설명한 적이 있습니다.link - [c#] 8. 配列とリストlink - [c#] 20. オブジェクト指向プログラミング(oop)の4つの原則(カプセル化、抽象化、継承化、多相化(ポリモーフィズム))オブジェクト指向プログラミング(oop)に関して簡単に改めて説明するとプログラムを開発する時、すべてをオブジェクト(object)に考えて開発することという意味です。つまり、オブジェクトというのはプログラムでクラス(class)の形で管理すること、またはこのオブジェクトを効果的に管理するためにリスト(list)とディクショナリ(dictionary)をよく使います。リストはデータ構造アルゴリズムでは連結リストアルゴリズムだし、ディクショナリ(dictionary)はマップアルゴリズムです。連結リストのアルゴリズムは始めから最後までのデータをポインタで連結したことだし、ディクショナリはキーと値で連結したデータ構造です。リストから0の値から9までのdataを持っているnodeインスタンスを順番とおりに格納されています。リストは確実に順番が決めているし、5番目のnodeインスタンスを取得してリストから取り除きました。そして、2番目のリストに100のdataを持っているnodeインスタンスを挿入しました。これかリストの特性です。ディクショナリ(dictionary)の場合は始めから最後までの順番が決めていることではなく、keyからデータを取得します。ディクショナリのkeyを通ってデータを入力して取り除く、出力しました。リストと違うのはデータが順番とおりにあることではなく、keyというデータを通ってデータが管理することを確認できます。参考でkeyの値はリストの形式で順番とおりに格納されていることではなく、keysでキーのリスト(?)を取得するとリストが順番とおりではないことを確認できます。c#はオブジェクト指向プログラム言語(oop)としてデータを管理するためにリストとディクショナリをたくさん使います。リストで上の例みたいに入力、出力することができますが、特定データを検索す

Study / C#

#C#

作成日付 : 2019/07/16 22:40:03       修正日付 : 2021/09/13 19:14:55

35

こんにちは。明月です。この投稿はvarキーワードとdynamicキーワードに関する説明です。以前の投稿でプログラムのstackメモリとheapメモリの関係に関して説明したことがあります。link - [c#] 11. インスタンスう生成(new)とメモリ割り当て(stackメモリとheapメモリ)そしてヌル(null)変数で宣言されているデータタイプはheapに生成するインスタンスのポインタのアドレスということで説明したことがあります。このポインタのアドレスというのは大きいデータがあることではなく、普通の整数になっているデータです。それで、一々にクラス名に合わせてソースを作成することは面倒くさいことですね。それで、この変数のデータタイプを作成しやすいようにするキーワードがありますが、それがvarキーワードです。上の例の結果をみればnodeの変数とnode1の変数の差異はソース上で作成するところでnodeのクラスタイプからvarタイプに変わったことだけで、プログラム上で実装する処理に関して同じです。つまり、varキーワードとは変数で宣言を簡単にするためのキーワードだけで、性能と処理に関してはなにも影響はありません。それでc#のソース規約(コーディングに関する規則)に従うとローカル変数宣言はvarキーワードを使うのをお勧めします。でも、このvarキーワードには何個か制約条件があります。最初の宣言する時にnullで設定はできません。そして最初の宣言したタイプは途中でタイプ変更はできません。そしてvarキーワードは関数のスタック領域だけ、つまりローカルだけ使うことができるしメンバー変数や関数のリターン値、パラメータは使えません。改めてまとめると、varキーワードは最初の宣言した原始データあるいはクラスタイプで設定ができるし、次は設定を変わりません。なので、当然に最初宣言する時にタイプを設定するのでnullは使えないし、メンバー変数とリターンタイプ、パラメータタイプでは設定を区分することができないので使えません。c#にはvarキーワードと似ているdynamicキーワードがあります。dynamicキーワードはvarキーワードと似ていますが、最初に宣言する時にデータタイプが決定することではなく、基本データタイプのobjectで設定があります。objectクラスに関して簡単に説明するとc#ではクラスが最小単位です。c#で

Study / C#

#C#

作成日付 : 2019/07/16 20:41:27       修正日付 : 2021/09/10 21:16:32

36

こんにちは。明月です。この投稿はc#で例外処理(try ~ catch)する方法に関する説明です。我々がプログラムを作成したら予想できないエラーが発生する場合があります。例えば、プログラムを作成する時に変数の値がない場合(nullエラー)か、正数の値に割り算をする時に整数を0で割る場合かの問題が発生することがあります。プログラムの実行中でエラーが発生しました。普通のプログラムの実行中でこんなエラーが発生すれば、エラーが発生した部分を飛び越えてプログラムが進めることではなく、プログラムがそのままに止まることになります。もちろん、上の例みたいに宣言された変数の値が間違ったら、変数の値を直したら解決しますが、もし、ユーザが受け取ったデータが間違えたり、データベースの値が予想しない場合にはプログラムを止まることではなく、例外処理をするべきです。つまり、エラーが発生してもプログラムが止まったり、終了されたらダメです。結果をみれば割る領域でエラーが発生しますが、エラーメッセージをコンソールに出力して"press any key..."のメッセージまでコンソールに出力されました。つまり、エラーが発生してもプログラムが止まらなくて最後まで実行されることを確認できます。エラー処理というのはエラーの区分によりcatchのスタック領域を分けることができます。上のtry領域では割り算エラーが発生しましたので、dividebyzeroexceptionのスタック領域に移動します。もし、try領域でdividebyzeroexceptionではないエラーが発生すれば、すべてのエラーをキャッチするexception領域に移動します。(ここでエラークラスの種類を分かる方法は始めにexceptionを作ってエラーを発生するとどのエラーが発生するかエラーメッセージで表示されます。始めの例を参考)普通の一般コードならすべてのexceptionで処理しても構いないですが、発生するエラー別で処理することが違いなら上のソースみたいにエラー別で区分する作業が必要です。つまり、exceptionですべてのエラーをキャッチしても別に性能上で問題ありません。そうなら我々がクラスを作成する時にクラスの特性上によりわざわざエラーを発生する時があります。上の例では私がエラークラスを作成しました。このエラークラスは基本的にexceptionクラ

Study / C#

#C#

作成日付 : 2019/07/16 00:59:34       修正日付 : 2021/09/09 19:10:28

37

こんにちは。明月です。この投稿はc#でのイベント(event)キーワードを使い方に関する説明です。プログラム言語ではイベント(event)の意味ではユーザの行動あるいはプログラム的にはアクションが発生する時、実行される関数という意味です。つまり、ウィンドウフォームでボタンがある場合、ユーザがボタンをクリックすると実行される関数という意味です。上の例では簡単なウィンドウフォームを作成しました。実行するとボタンがあるウィンドウフォームが生成されますが、ここでボタンをクリックするとbuttton_click関数が呼び出して実行されます。こんなアクションをイベントと言います。我々が以前の投稿で似ている機能に関して、デリゲート(delegate)で説明したことがあります。link - [c#] 23. デリゲート(delegate)上のソースはコンソールからユーザで入力イベントを受け取ったらprint_event関数を発生します。ここまでみるとデリゲートだけでイベント関数を実装しました。ここまでだけでもイベント関数を実装することでは問題がありませんが、実はここにはオブジェクト指向プログラミング(oop)のルール違反があります。それがconsolecmmandのデリゲートリストです。上のデリゲートの呼び出しをコンストラクタ中でユーザから入力が発生すると実行する役割です。でも、このリストがpublicで設定されているので、list("")形式でmain関数でも実行できることが欠点があります。つまり、外部からはイベント関数を連結することが可能にしますが、実行はできないようにするべきです。それがeventキーワードです。上の例をみればmain関数でデリゲートを実行しました。実はこんなことになるとクラス中で縛っているイベントが外部から強制(?)に実行される問題があります。それならデリゲートの前でイベント付けたらどのようになるか?コンパイル段階でエラーが発生しました。つまり、イベントの関数を外部で付けることは可能ですが、実行はクラス中だけで実行することが可能です。要約すればイベント関数は以前のデリゲートから実行を我部で実行できないためのキーワードです。ここまでc#でのイベント(event)キーワードを使い方に関する説明でした。ご不明なところや間違いところがあればコメントしてください。

Study / C#

#C#

作成日付 : 2019/07/16 00:48:03       修正日付 : 2021/09/08 18:18:07

38

こんにちは。明月です。この投稿はc#でラムダ式(匿名関数)とaction、func関数を使い方、そしてクロージャ(closure)に関する説明です。以前の投稿でデリゲート(delegate)に関して説明したことがあります。link - [c#] 23. デリゲート(delegate)デリゲートとは関数ポインタで関数をインスタンスのポインタみたいに管理ができるような機能ということです。つまり、関数をポインタで管理ができればもっと考えると関数の名前が要らずに関数を作成することができます。ラムダ式とは匿名関数の意味とおりに関数名せずに作成が可能な関数です。上の例をみれば返却式はなく、stringのパラメータを受け取るデリゲートを作成しました。そしてmain関数で(val) => {}の形式のラムダ(匿名関数)を作ってデリゲートリストに追加しました。ここでvalのデータタイプはデリゲートで宣言したstringのタイプのデータになり、返却タイプはないのでreturnは要りません。そして中括弧({})のスタック領域で関数が呼び出したら実行するプログラムのコードを実装します。実行すればlistのデリゲートを実行して登録されて二つのラムダ式が実行することを確認できます。そうならこのラムダ式を使うためにはそれを合わせてデリゲートを常に宣言するべきだと思いますが、func関数とaction関数を利用すればデリゲートが要りません。上の例では匿名関数を作成しましたが、delegateを宣言せずにfuncとaction関数を使いました。func関数は返却値がある匿名関数で、action関数は返却値がない匿名関数です。func関数の最後のパラメータは返却値のデータタイプです。その以外は順番とおりのパラメータのデータタイプです。ラムダ式というのは実は文法規約を破壊する方法です。ラムダ式が使うことも楽だしデリゲート(delegate)やリストとfunc、actionを適当に混ぜて作成するならプログラムを実装する時に凄く楽になります。問題はラムダ式が多くなるとソースは凄く複雑になるし、可読性が凄く悪くなる欠点があります。そのため、一般関数を使うことができれば関数名を作成してラムダ式を使うことを抑える方が良いです。そうならラムダ式をいつ使うほうが良いか?デザインパターンのオブザーバーパターンを実装する時、つまり、イベントやコー

Study / C#

#C#

作成日付 : 2019/07/16 00:36:19       修正日付 : 2021/09/07 20:47:10

39

こんにちは。明月です。この投稿はc#のデリゲート(delegate)を使う方法に関する説明です。c#のデリゲートは代理子のいう意味でc++の関数ポインタと似ている概念を持っているキーワードです。つまり、関数ポインタとは関数式(function)をインスタンスのポインタみたいに認識して変数に値を格納するかパラメータに渡して実行する代理に実行する役をします。上の例でprint関数をデリゲートで使ってポインタでインスタンスのポインタを変換してpdの変数をインスタンス値みたいに使えます。実行はデリゲートの変数でただ関数を呼び出すみたいにパラメータ値を入れれば実行されて、コンソール出力することを確認できます。上の式はデリゲートを説明するために凄くシンプルに作成したことで実際は変数の値みたいに使ういい点があります。上の例をみればexample클래스とnode1、node2クラスをinodeインタフェースを継承しました。上の形式はデザインパターンの中で合成パターンです。exampleクラスにnode1クラスのprint関数とnode2クラスのprint関数を入れてexampleクラスのprint関数を実行すれば同時に実行されるパターンです。上の例は私がlistにデリゲートを格納して関数ポインタを管理するようにしました。でも、デリゲートは関数を管理するリスト機能もあります。+=と-=の対入演算子を通って追加、削除をできます。上の例には二つ目のlistクラスの変わりにデリゲートで関数式を追加、削除することができます。最近にはc#コードでラムダ式(lambda)をよく見えますが、このラムダ式がデリゲート基盤で生成して使います。ラムダ式は匿名関数の意味で関数で名前がない関数という意味です。このラムダ式は関数名が存在しないので関数ポインタだけ存在します。つまり、ラムダ式を使うためにはこのデリゲートで関数のポインタを持つべきだと意味です。ラムダ式はラムダ式を説明する時にもっと詳細に説明します。ここまでc#のデリゲート(delegate)を使う方法に関する説明でした。ご不明なところや間違いところがあればコメントしてください。

Study / C#

#C#

作成日付 : 2019/07/15 02:25:26       修正日付 : 2021/09/06 18:56:03

40

こんにちは。明月です。この投稿はc#のインデクサー(indexer)を使う方法に関する説明です。c#には他の言語にはない文法が何個かあります。その中で一つが以前の投稿で説明したプロパティ(property)です。link - [c#] 21. c#のプロパティ(property)この投稿もc#の特別な文法のインデクサー(indexer)です。インデクサー(indexer)は簡単に説明すると配列の形で関数を呼び出す機能です。文法の形はプロパティ(property)と似てます。上の例をみれば私がnodeクラスでインデクサー(indexer)関数を作りました。インデクサー(indexer)はプロパティの文法みたに配列の値を受け取るデータタイプと入力するデータタイプを設定して関数名にはthisキーワードを使います。そして配列みたいに使うので、配列のインデクサー役でstring値を格納するし、イコールでデータは返却データタイプで値を格納します。mainの実行関数でnode[string] = intの形で実装するとset関数が呼び出すし、node[string]の型で実装するとget関数が呼び出します。文法がプロパティ(property)と似てます。なのでアクセス修飾子を設定する方法も似てますが、基本のアクセス修飾子はgetで設定して、set関数だけ別途にアクセス修飾子を設定することができます。プロパティ(property)とインデクサー(indexer)は他の言語にはない文法です。この文法があることはオブジェクト指向プログラミング(oop)のカプセル化により、メンバー変数をprivateに設定しますが、ゲッター、セッターを少し効率的に格納、取得するための文法です。でも、プロパティの場合はよく使いますが、インデクサー(indexer)はよく使いません。なぜかというと配列と似ている形なので、逆に迷う時が発生します。ソースコードは可読性、つまり、ソースを読みやすく作ることが重要ですが、インデクサー文法が多いソースは逆に迷い込みやすいです。そのことでよく使わないですね。特にc#だけ開発するデベロッパー(開発者)の方はインデクサー(indexer)が凄く読みやすいっていうかもしれませんが、javaやpythonなどの他の言語がメインのデベロッパー(開発者)の方は難しいというかもしれません。その理由かな、実務プロジェクトでも

Study / C#

#C#

作成日付 : 2019/07/13 01:06:04       修正日付 : 2021/09/03 17:21:01

41

こんにちは。明月です。この投稿はc#のプロパティ(property)に関する説明です。以前の投稿でオブジェクト指向プログラミング(oop)の4つの原則とアクセス修飾子、カプセル化に関して説明したことがあります。link - [c#] 12. staticとアクセス修飾子、そしてカプセル化link - [c#] 20. オブジェクト指向プログラミング(oop)の4つの原則(カプセル化、抽象化、継承化、多相化(ポリモーフィズム))基本的にオブジェクト指向プログラミングでメンバー変数はprivateに設定してクラスの外部から接続ができないように設定します。そうならクラスのメンバー変数の値はすべてコンストラクタや関数を通ってデータを設定しますが、そのところでデータを格納、取得だけの関数があります。それをjava言語ではゲッター(getter)、セッター(setter)と言います。何でこのように実装するかというとメンバー変数はオブジェクト指向プログラミングによりメンバー変数はprivateに設定することが原則です。上の例は何の制限がなしてゲッター、セッターを設定したからデータ設定、取得することにしますが、ゲッター、セッターで権限により、あるいは設定によりデータのアクセスを制御することが可能です。例えば、メンバー変数をpublic設定する場合は読み込み専用変数や書き込み専用変数に設定ができないですが、ゲッター(getter)だけ実装すると読み込み専用、セッター(setter)だけすると書き込み専用の変数に設定することができるし、また、ログなどを設定してデバッグする時にcall stackヒストリにより参照追跡も可能です。なので、オブジェクト指向プログラミング(oop)ではメンバー変数をpublicを設定することではなく、privateに設定してゲッターやセッターにより設定、取得するように実装します。c#ではjavaとは違い、ゲッターとセッターを文法的に実装することがありますが、それがプロパティ(property)です。普通、メンバー変数はすべて小文字で作成して、プロパティはその変数名から始めの文字だけ大文字に設定します。その後、プロパティのデータタイプによりゲッターのリターンタイプが設定されるし、セッターのパラメータのデータタイプが設定されます。スタック領域の中で実装するのは、getの場合はgetterと似ているし、

Study / C#

#C#

作成日付 : 2019/07/13 00:56:20       修正日付 : 2021/09/02 17:36:37

42

こんにちは。明月です。この投稿はc#のオブジェクト指向プログラミング(oop)の4つの原則(カプセル化、抽象化、継承化、多相化(ポリモーフィズム))に関する説明です。オブジェクト指向プログラミング(object-oriented programming)とはプログラミングの方法の一つです。プログラミングの方法とは、プログラムを開発する時にどの目的の中心に開発しようということの意味です。その中でオブジェクト指向はオブジェクト(object)を中心にプログラムを設計、開発することの意味です。例えば、「業務計画書作成 -> 計画実行 -> テスト -> 結果確認 -> 報告書作成 -> 承認」のプロセスの業務があると思いましょう。ここで、まず全体の業務単位(controller)で構成して計画データ(object)、テストデータ(object)、結果データ(object)、報告書データ(object)、承認データ(object)をプロセスの流れで配置します。プログラム言語で考えば最小単位のクラスでオブジェクト(object)を作成して管理することがオブジェクト指向プログラミング(object-oriented programming)です。ごのオブジェクト指向プログラミング(object-oriented programming)には4つの原則がありますが、それがカプセル、抽象化、継承、多相化(ポリモーフィズム)です。その4つの原則に関しては部分的に他の投稿で説明したことがあります。link - [c#] 12. staticとアクセス修飾子、そしてカプセル化link - [c#] 15. インタフェース(interface)link - [c#] 14. 抽象クラス(abstract)と抽象メソッド(abstract)、そして仮想関数(virtual)link - [c#] 9. 関数(method)とオーバーロード、再帰呼び出しこの投稿ではその特性をもっと詳細に説明します。カプセル化カプセル化はクラスのアクセスを制限することです。例えば、クラスのメンバー変数と関数がすべてpublic(すべてアクセス可能)で作成する場合、クラスの固有の特性がなくなります。なので、クラスの特性を活かせるためにはクラスのデータ格納、取得する関数以外はpriva

Study / C#

#C#

作成日付 : 2019/07/12 00:17:35       修正日付 : 2021/09/01 18:47:47

43

こんにちは。明月です。この投稿はc#で列挙型(enum)を使う方法に関する説明です。我々がプログラムを作成する時に、固定値を使う場合があります。その時に変数の定数化(値が変わらない変数)を通って値を定義して使います。link - [c#] 3. プログラミングの始めと変数と定数を使う方法上の例をみればprintという関数のパラメータのタイプがintタイプなのでただ、1や2を入れても問題なく作動します。でも、実際のプロジェクトでコーディングする際にコード上でただ1や2で作成すると、次でコードを見る時に何の意味が分からない場合があります。それで意味を分かりやすくするために定数に変換して1や2の意味を分かるように作成します。上の例では私がtype1とtype2の定数を作成して意味を作ることです。実際にもこのようによく作成しますが、それも可読性の限界があります。typeaのパラメータにはatype1とatype2を使ってtypebのパラメータにはbtype1とbtype2を使います。私がソースを読みやすいためにtypeaのパラメータの定数とtypebのパラメータの定数を区分しておきました。でも、このパラメータのデータタイプはintタイプなので、区分してもtypeaパラメータにもbtype1やbtype2定数を使っても問題ありません。でも、そのルールを従って作成しないと、後でソースを解析する立場で意味が可笑しくなります。可読性が悪くなることも当たり前です。それを整理することが可能にするものが列挙型(enum)です。定数を列挙型に纏めてtypeaのパラメータにtypebを入れることや数の1を入れて間違いコーディングを作成することができないし、可読性が悪くならないことにして、綺麗なソースコードを作成することができます。列挙型は単純な定数の値を処理することではなく、bit flag値を設定して、もっと読みやすいソースコードを作成することができます。上の例はビットのtype1とtype4、type7をor演算処理してパラメータに渡して、and演算処理してデータのflag情報を取得することができます。つまり、一つの変数でflagの情報を格納、取得ができます。tostring関数を利用すると列挙型の値ではなく、ソースに作成した列挙型の文字が出力します。私は新入社員の際に先輩からプログラム作成する時に定数、変数の宣言の以外にソー

Study / C#

#C#

作成日付 : 2019/07/11 23:13:25       修正日付 : 2021/08/31 19:42:39

44

こんにちは。明月です。この投稿はc#で構造体(struct)、そして値型を参照するタイプ(reference of value type)と参照型を参照するタイプ(reference of reference type)に関する説明です。以前の投稿でクラスとインスタンス生成に関して説明したことがあります。link - [c#] 10. クラスを作成する方法(コンストラクタ、デストラクタ)link - [c#] 11. インスタンスう生成(new)とメモリ割り当て(stackメモリとheapメモリ)そしてヌル(null)基本的にc#で構造体というのはクラスと似ています。上の例をみればクラスを作成することと構造体を作成することは同じですね。クラスと構造体が何の差異があるかとみれば値型を参照するタイプ(reference of value type)と参照型を参照するタイプ(reference of reference type)があります。つまり、クラスの場合はheapメモリにクラスのインスタンス生成してstackメモリに変数を設定してインスタンスのポインタを格納します。そうしたら、他の変数にイコール(=)を使ってポインタ値を格納するかパラメータでポインタを渡した後、インスタンスの値を変更したら、他に連携したインスタンスにも影響になります。上の結果をみればexの変数のdataの値が変わっています。つまり、クラスの参照するタイプ(reference of reference type)は下記とおりに連携しています。クラスの連携構造は以前に説明したことがあります。でも構造体がクラスと違いいます。上のソースは以前のexampleクラス(class)で構造体(struct)に変更したことしかありません。でも、結果は違います。構造体の連携図をみれば下記通りになります。構造体はイコール(=)でポインタコピーではなく、インスタンスがコピーされています。これが値型を参照するタイプ(reference of value type)と言います。つまり、我々が原始データを扱う時、つまり、int a=1;int b=a;ということに設定する場合、変数のbを設定したら変数のaの値は変わらないです。これが値型を参照するタイプ(reference of value type)です。でも、この構造体(struct)を関数のパラメータにデータ

Study / C#

#C#

作成日付 : 2019/07/10 23:57:25       修正日付 : 2021/08/31 18:20:54

45

こんにちは。明月です。この投稿はc#のthisとbaseのキーワードに関する説明です。以前の投稿でクラスのインスタンスを生成する方法に関して説明したことがあります。link - [c#] 11. インスタンスう生成(new)とメモリ割り当て(stackメモリとheapメモリ)そしてヌル(null)クラスの構成は基本的にメンバー変数と関数があります。c#にはプロパティやデリゲート、イベントなどがありますが、全部関数の変形型なので、関数で思えば良いです。ここで我々がクラスを継承する時に親クラスのメンバー変数、関数を参照する時もあるし、本クラスを参照する時があります。その時に再定義する場合、関数名が同じなので参照する区分が必要です。また、関数の中で、メンバー変数名とパラメータ名が同じの場合は?上の例をみればexampleクラスのprint関数にはパラメータ名をdataで受け取ってクラスのメンバー変数にはdataの変数名があります。この場合に関数の中でdata変数を呼ばれると基本的にstack領域の内部のdataを参照します。つまり、パラメータのdataを参照します。そうならstackで同じ名の変数名がある場合にメンバー変数のdataを使うことできないかな。そのため、thisキーワードがあります。インスタンス中でthisの意味は本クラスのインスタンスを指すことになります。つまり、this.dataということに使うとメンバー変数を指すことになります。上の例をみれば、this.dataはメンバー変数を指しているので、結果が10になることを確認しました。少し正確にインスタンスのポインタアドレスで確認しましょう。上の例でex変数名になっているインスタンスでgetinstance関数を呼び出してthisでリターンします。thisはexのインスタンスを指すことです。リターンを受け取ったex1のhashcodeをみればexと同じインスタンスって確認できます。そうならthisは自分のインスタンスを指していますが、継承する場合に親クラスを参照する必要がある時があります。subexampleでgetdata関数を再定義しました。しかし、仕様により親クラスのgetdata関数を参照したい時があります。その場合はthisではなく、baseキーワードで参照することができます。上の場合はprint関数でbaseキーワードを使っているので親ク

Study / C#

#C#

作成日付 : 2019/07/10 23:43:56       修正日付 : 2021/08/27 14:37:25

46

こんにちは。明月です。この投稿はc#の継承禁止のキーワードのsealedに関する説明です。以前の投稿でクラスを継承する方法に関して説明しました。link - [c#] 13. クラスの継承と再定義(override)する方法、overrideとnewの差異クラスを継承する理由に関して簡単に説明すると同じコードの作成を避けるし再使用率を高めるために使います。しかし継承することで親クラスを直接参照ができることになります。もし、ライブラリを配布する立場ならセキュリティや様々な理由でクラスの継承をできないようにする場合もあります。例えば、我々がよく使うstringクラスがありますが、このstringクラスは他のクラスと違い、ソース上の文字列なリートンネルを直接に読み込みする機能(string a = "test"; つまり、インスタンス生成なnewキーワードを使わなく、ソース上の直接にstringで割り当て変換)があるため、stringクラスを継承すると様々な部分で効率的にプログラムを再構成することができます。しかし、よく使えることならそうですが、すべてのプロジェクトが設定と規約通りに作成しないので、プロジェクトを進めるときっと始めの意図より違いに使うことになり、stringのオブジェクトを継承するクラスは実は拡張文字列を作りたかったと思いますが、変なクラスになり、後は凄く複雑なプログラムができる可能性が高いです。(例、c++のoperatorと前処理問い合わせ欠点)そのため、その問題を発生しないため、継承禁止するキーワードが必要ですが、それがsealedキーワードです。単純にクラス前にabstractキーワードみたいにsealedキーワードを入れれば継承禁止になります。visual studioでエラーを発生してコンパイルからできないです。クラス継承はできますが、関数の再定義をてきないように設定することもできます。上の例はexampleクラスをsubexampleクラスが継承して、subexample2クラスがまたsubexampleクラスを継承しました。ここでprint関数をsubexampleクラスでexampleクラスから再定義して、subexample2クラスでsubexampleクラスから再定義しようと作成しましたが、subexampleクラスからprint関数をsealed設定し

Study / C#

#C#

作成日付 : 2019/07/10 00:19:18       修正日付 : 2021/08/27 11:36:05

47

こんにちは。明月です。この投稿はc#のインタフェース(interface)に関する説明です。以前の投稿でインスタンスを生成する方法と継承に関して説明しました。link - [c#] 11. インスタンスう生成(new)とメモリ割り当て(stackメモリとheapメモリ)そしてヌル(null)link - [c#] 13. クラスの継承と再定義(override)する方法、overrideとnewの差異クラスの共通的な内容を抽象クラスで作成して継承しながらクラスを定義することに関して説明しました。でも、c#では二つ以上の抽象クラスを継承することができません。エラーが発生します。理由としては、複数継承エラーです。複数の継承でも上みたいに使うと問題がなさそうです。でも、print関数がexampleのクラスではなく、抽象クラスにある関数なら。継承するクラスではatypeabstractclassのクラスの関数が使うかbtypeabstractclassのクラスの関数が使うかを分からなくなります。それでc#には複数の継承を禁止させています。上の話はheapメモリの中でも話です。それならstackメモリに変数を宣言する時にはオブジェクトの特性上のオブジェクト別に片付ける必要がある時があります。exampleクラスを見ればiatypeinterfaceのインタフェースとibtypeinterfaceのインタフェースを継承しました。つまり、iatypeinterfaceのインタフェースの関数とibtypeinterfaceのインタフェースの関数を再定義すべきです。それで二つのインタフェースを継承したexampleクラスは二つのインタフェースの関数を再定義しました。aexampleクラスの場合はiatypeinterfaceインタフェースを継承したので、iatypeinterfaceインタフェースの関数を再定義しました。bexampleクラスの場合はibtypeinterfaceインタフェースを継承したので、ibtypeinterfaceインタフェースの関数を再定義しました。そしてmain関数でインスタンスを生成してprint関数を呼び出ししました。インタフェースは抽象クラスと違うのが中でメンバー変数と一般関数を実装することができません。ただ、定義だけします。そうなので、継承する関数では再定義(override)のキーワ

Study / C#

#C#

作成日付 : 2019/07/10 00:06:17       修正日付 : 2021/08/26 17:00:48

48

こんにちは。明月です。この投稿はc#で使う抽象クラス(abstract)と抽象メソッド(abstract)、そして仮想関数(virtual)に関する説明です。以前の投稿でクラスの継承、再定義する方法に関して説明したことがあります。link - [c#] 13. クラスの継承と再定義(override)する方法、overrideとnewの差異クラスの継承は基本的にクラスの機能をそのままに引き続きに継承して新しくクラスを拡張、修正する概念だと説明しました。そのところで、親クラスは継承する前にもインスタンスを生成して使えますが、今回はクラス自体は使えない不完全なクラスでただ継承して再定義してから使うクラスを紹介します。つまり、クラス自体をインスタンス生成が不可能で継承して再定義して使えるという意味です。上の例をみればabstractexampleクラスのgetdata関数は宣言だけして内容は実装してないです。そしてクラスと関数の前にabstractのキーワードを使いました。それならabstractexampleクラスは抽象クラスになり、getdataは抽象メソッドになります。つまり、抽象クラスは未完成クラスで抽象クラス自体はインスタンス生成ができなくて、必ず継承してから使えます。また、抽象メソッドは継承するクラスで必ず再定義(override)すべきになります。なので、exampleクラスで抽象クラスのabstractexampleクラスを継承する時に抽象メソッドを再定義(override)しました。この抽象クラスを使う目的は多いクラスの共通部分を一つに取り縛って共通クラスとして実装する時によく使います。上のmain関数で指示子は抽象クラスでインスタンス生成して割り当てするのは継承したクラスです。その関係に関しては以前の投稿で説明したことがあるのでご参考してください。link - [c#] 11. インスタンスう生成(new)とメモリ割り当て(stackメモリとheapメモリ)そしてヌル(null)またmain関数をみるとforeachでprint関数を呼び出します。指示子の抽象クラスには実装はしてないですが、print関数が宣言されています。なので、print関数を呼び出して各インスタンスの関数を呼び出すことができます。結果はprint関数の文言と各インスタンスで再定義した関数getdataの結果がコンソール

Study / C#

#C#

作成日付 : 2019/07/08 23:04:09       修正日付 : 2021/08/20 19:17:30

49

こんにちは。明月です。この投稿はc#でクラスの継承と再定義(override)する方法、overrideとnewの差異に関する説明です。プロジェクトでクラスを作成する時に既存にあるクラスと似てますが、少しずつ違うクラスを作成する場合があります。また、クラスを修正する時に初期開発の場合はただ修正して使いますが、もし運用中なら既存クラスを勝手に修正すると参照するところでエラーが発生する場合があるので、既存のクラスと似てるクラスを新しく作成するしかないです。その時に一番簡単な方法はただクラスをコピペして作成したら楽です。例として、我々が10個のクラスをコピペしてクラスを作成しました。でも、コピペした元のクラスでエラー(バグ)が発生しました。その場合はコピペしたクラスを修正するために10回に修正するべきになります。簡単なプログラムならそれでもできる範囲ですが、仕様が大きいプログラムなら10個だけではなく、100個以上になる可能性もあるので、それをすべて修正することは簡単な話ではありません。参考に実務でもこんなに作成したケースが多いですね。なので、プログラム言語では既存のクラスの機能をそのままに持ってきて拡張、修正する機能がありますが、それを継承といいます。上の例をみればcopyexampleというクラスはexampleのクラスから継承しました。クラスの継承はクラスを生成する時に隣でコロン(:)を付けて親クラスを指定するとクラスが継承になります。実際にmain関数でcopyexampleクラスのインスタンスを生成して関数を呼び出すとexampleの機能をそのままに使えることを確認できます。クラスを継承すると親クラスの機能をそのままに持ってきて関数やメンバー変数を新しく追加することができます。しかし、親クラスの関数や変数でそのままに使わなくて再定義する時もあります。上の例でcopyexampleクラスでnewキーワードを使って関数を再定義しました。結果は親クラスのprintの値ではなく、再定義した結果がコンソールに表示されます。実は再定義キーワードはoverrideです。このoverrideは親クラスで再定義を許した場合(abstractやvirtual)に使います。しかし上みたいに親クラスの一般関数を再定義する時にはnewキーワードを使ったらよいです。上の例はexampleクラスでprint関数にvirtualキー

Study / C#

#C#

作成日付 : 2019/07/08 22:55:00       修正日付 : 2021/08/18 15:17:07

50

こんにちは。明月です。この投稿はc#でstaticとアクセス修飾子、そしてカプセル化に関する説明です。以前の投稿でインスタンス生成とstackメモリとheapメモリに関して説明しました。link - [c#] 11. インスタンスう生成(new)とメモリ割り当て(stackメモリとheapメモリ)そしてヌル(null)c#では基本的にnewのキーワードでクラスのインスタンスを生成してheapメモリにインスタンスを割り当てしてメンバー変数や関数などを呼び出して使えます。このことがc#の最小の実行単位になります。それならmain関数はどうでしょう。つまり、我々が実行関数と呼ばれるmain関数を呼び出すためにはクラスのインスタンスを何処で生成して割り当てするでしょう。改めて考えると我々が関数を呼び出すためにはインスタンス生成が必要です。つまり、鶏が先か、卵が先かの話ですね。関数を呼び出すためにはインスタンスが必要、ならインスタンスを何処で生成する?それであるキーワードはstaticです。このstaticが付けているクラス、関数、変数はプログラムが開始する時にstackメモリに登録します。つまり、インスタンスの生成がなくても関数や変数を使えるという意味です。上の例をみればexampleクラスのインスタンスを生成せずに、print関数を呼び出すことができます。その中でmain関数は少し特別な規約がありますが、staticが付けられたmain関数はプロジェクトの中で必ず一つだけです。プログラム内でmain関数が二つなら開始の実行関数が分からなくなるのでです。このstaticキーワードは関数だけではなく、変数にも付けることができます。上の例をみればexampleクラスのインスタンスを二つ生成して各のインスタンスのメンバー変数にデータを格納しました。でも結果はex1とex2のインスタンスのメンバー変数が同じ値が出力されます。つまり、exampleのdataメンバー変数はインスタンスと関係ずにプログラムが実行する時に生成する変数だからです。それならインスタンスと関係ないのでmain関数から直接にメンバー変数を参照することができると思いますが、実はprivateというアクセス修飾子により参照ができません。アクセス修飾子は実行する位置(ステップ)でクラスや関数、変数を参照する権限(?)と思えば良いです。

Study / C#

#C#

作成日付 : 2019/07/07 23:12:30       修正日付 : 2021/08/04 19:29:21

51

こんにちは。明月です。この投稿はインスタンスう生成(new)とメモリ割り当て(stackメモリとheapメモリ)そしてヌル(null)に関する説明です。以前の投稿でクラスを作成する方法に関して説明したことがあります。link - [c#] 10. クラスを作成する方法(コンストラクタ、デストラクタ)クラスを作成してインスタンスを生成する方法でnewというキーワードを使います。ここでexample ex = new example(int)の意味はexampleタイプのex変数にnew exampleのインスタンスを生成してintタイプのパラメータを持つコンストラクタを呼び出すことの意味です。先に確認しべきなところは変数の宣言です。以前に変数宣言に関して説明したことがありますが、変数宣言にはデータタイプと値が一致しなければならないです。つまり、intタイプに実数タイプを格納するか文字列を格納することができないみたいにexampleタイプには必ずexampleクラスのインスタンスが格納しなければならないです。このexample exは割り当てメモリアドレスを指していることで一応ポインター変数といいます。つまり、変数に値が格納することではなく、メモリアドレスが格納することです。上のイメージみたいな構造になります。ここでstackメモリとheapメモリの構造が表させています。stackメモリは我々がプログラムで関数を作成する時に実行領域を設定する中括弧({})があります。この中括弧の領域を我々はstack領域といいます。このstack領域で宣言する変数の値はstackメモリに格納することで思えば良いです。上のイメージを見ればmain関数の中で任意な中括弧を使って新しいstack領域を生成しました。その新しいstack領域でintタイプのdata変数を宣言しましたが、領域の外側で使ったら存在しない変数というエラーメッセージが表示されます。つまり、example exはmain関数のstack領域で宣言した変数という意味になります。new example(10)はheap領域で割り当てしたインスタンスですが、heapはプログラムの領域のメモリ構造です。つまり、プログラムが実行する時にheapメモリの領域が生成してそのメモリの領域を自由にインスタンスを生成したり解除したりすることが可能です。プログラムが終了するとhea

Study / C#

#C#

作成日付 : 2019/07/07 22:54:13       修正日付 : 2021/08/02 15:07:51

52

こんにちは。明月です。この投稿はc#でクラスを作成する方法(コンストラクタ、デストラクタ)に関する説明です。c#でクラスはプログラムを実行するための最小単位の要素です。つまり、プログラムを実行するために必ず作成しなければならない要素という意味です。今までの投稿で我々はmain関数の実行関数を作成して実装しました。しかし、main関数を作成した構造をみるとmain関数を囲まれているprogramのクラスがあるし、クラスを囲まれているexampleのネームスペースがあります。(参考にネームスペース(namespace)は省略してもc#のプログラムを作成することでは問題ありません。)上の例をみればnamespaceを除いてprogramクラスだけ生成してその中でmain関数を作成してプログラムを最小単位を設定して実装しました。エラーがなくてちゃんと実行されます。クラスには作成する構造があります。 クラスの要素 説明 コンストラクタ インスタンスが生成する時(メモリにクラスを割り当て)に呼び出す関数、関数で返却がなしでコンストラクタ名はクラス名と同じです。 デストラクタ インスタンスがなくなる時(gcによりメモリ上で解除)に呼び出す関数、クラス名と同じで前に「~」を付けること。 メンバー変数 フィールドというメンバー変数、クラスないで使う変数 プロパティ 実行する動作は関数と同じですが、プログラムで使う形式は変数と似ている関数(getter、setter) インデクサー クラスを配列文法を使って使える関数

Study / C#

#C#

作成日付 : 2019/07/06 00:53:17       修正日付 : 2021/07/16 20:45:02

53

こんにちは。明月です。この投稿はc#の関数(method)とオーバーロード、再帰呼び出しに関する説明です。以前の投稿までの例をみればmain関数(実行関数)でソースの上行から下行まで順番に実行されます。この形式で制御文だけでもプログラムを作成することができます。でも、プログラムが複雑になるし、大きくなるとこの形式だけでは限界があります。そのため、その長くなるソースを解決するために、関数(method:メソッド)でソースを分割して作成することができます。参考にプログラムの関数は数学の関数と同じ意味です。任意の元素(パラメータ)を代入して結果を返却してもらう数学の二項関係式です。関数のパラメータにデータを入れると関数の中の演算をして返却データタイプにデータに合わせてデータを返却してもらいます。上のソースでexecutemethod1関数とexecutemethod2関数を作成しました。関数の前にあるキーワードでprivateはアクセス修飾子です。staticは静的タイプに設定するキーワードですが、そのことについては別の投稿で説明します。また、データタイプを設定しますが、intの場合は関数から整数のデータタイプの値が返却するという意味です。なので、関数の中では必ずreturnキーワードを作成しなければならないし、returnデータタイプは必ずintタイプで返却しなければならないです。voidの場合は返却がないという意味のデータタイプで関数の中でreturnキーワードでデータを返却する必要がないです。(返却データタープがvoidの場合、returnを使うとreturnキーワードがあるところで関数を終了します。)パラメータはintタイプで受け取ります。パラメータの場合は関数により必須項目ではなく、パラメータが無いことで関数を作成することができます。main関数(実行関数)でexecutemethod1関数とexecutemethod2関数を呼び出しました。まず、executemethod1関数からはintタイプのパラメータを要求するので、intタイプの変数のaを渡します。a変数で5の値があるのでexecutemethod1関数を通ると5掛けて10になり、返却データは50になります。ret変数にはxecutemethod1関数の返却値を格納するので、50のデータがあります。executemethod2関数にはret変

Study / C#

#C#

作成日付 : 2019/07/06 00:38:29       修正日付 : 2021/07/14 20:20:43

54

こんにちは。明月です。この投稿はc#の配列とリスト(list)に関する説明です。配列とは同じデータタイプのデータを連続的に格納するデータタイプです。(参考に連続的に格納することは論理的です。c++と比べてc#はstackメモリ割り当てがないので、物理的には連続ではありません。)上の例では配列を10個宣言しました。つまり、intタイプの変数が10個あることです。配列のインデクスは0から始まります。結果は変数名一つで10個のデータが格納しました。上の例みたいな配列を一次配列といいます。つまり、一列にデータがあると想像できますね。そうなら、多次配列もあります。配列は単純に変数名を一つで何個のデータを格納することの目的ではないです。データが論理的に連続であることを考え、整列などで使うことができます。整列のは無作為にあるデータを昇順、降順に順番を片付けることです。初期に配列変数に整列しようと思うデータを格納しました。配列状況を確認するため、無作為なデータを格納しました。ここで配列0番目と次の位置のデータを比較して大きいデータが高次数に移動するように計算します。0番目の比較が完了すると1番目と次の位置のデータを比較します。この繰り返しで最高の位置の前のデータまで比較します。(最高の位置のデータは比較する対象がありません。)この方法で整列することをバブル整列といいます。次はデバッグ表です。 入力値 512 64 24 7 23 623 1 5 17 10 1次整列 64 24 7 23 512 1 5 17 10 623 2次整列 24 7 23 64 1 5 17 10 512 623 3次整列 7 23 24 1 5 17 10 64 512 623 4次整列 7 23 1 5 17 10 24 64 512 623 5次整列 7 1 5 17 10 23 24 64 512 623 6次整列 1 5 7 10 17 2

Study / C#

#C#

作成日付 : 2019/07/05 00:12:42       修正日付 : 2021/07/13 21:04:45

55

こんにちは。明月です。この投稿はc#の制御文に関する説明です。プログラムで制御文というのはプログラムの処理順番を制御するか繰り返して実行することの制御回数を決定することの意味です。改めて簡単に説明すると、プログラムのコードは基本的にソースの上の行から下の行の向きで処理します。単純に上から下の行に処理の流れの中で繰り返して処理する内容があることもあるし、処理を飛び越える部分、省略しなければならない処理がある可能性があります。この繰り返し、飛び越える、省略する処理を制御文といいます。制御文は選択文、繰り返し文、分岐文があります。選択分は条件により真偽の可否により処理する制御文です。種類はif~else文、switch~case文があります。繰り返し文は一定な条件が満たす時まで同じ処理を繰り返して処理する制御文です。種類はfor文、while文、do~while文、foreach文があります。分岐文は流れの処理順番を変わることにする制御文です。break文、continue文です。if~else- if~else文は真偽の可否により処理する制御文ですif文の条件が真(true)なら該当なスタックが実行する構造です。最後にelseがあればすべての条件が偽(false)なら実行する流れです。上の例を説明すれば始めの条件でaの変数の値を確認します。aのブール値がtrueならif(a)のスタック領域が実行されます。aという変数にtrueの値を格納しましたので、コンソールに「first condition = true」というメッセージが出力しました。二つ目の条件式はif~elseの条件式です。変数aがtrueならif(a)のスタック領域を実行するしfalseならelseのスタック領域を実行します。二つ目の条件式前に私がaの変数の値をfalseを格納しましたので、コンソールに「second condition = false」というメッセージが出力しました。三つ目の条件式は変数bの値を関係演算子でtrue、falseの値を計算します。bの値を2で設定しましたので、if(b==2)の条件が真(true)になるので、コンソールに「third condition b = 2」というメッセージが出力しました。switch~case- switch~caseは選択文ですが、if~else if~elseと似ている処理をします。sw

Study / C#

#C#

作成日付 : 2019/07/05 00:05:30       修正日付 : 2021/07/12 20:12:48

56

こんにちは。明月です。この投稿はc#の演算子に関する説明です。我々がパソコンを使う時にゲームもするし、様々な業務のためにデータを格納するかプログラムを作りますが、実は性能がすごくよい計算機です。つまり、グラフィックを描画や業務のためのプログラムはすべて計算により出力することです。なので、プログラム中で一番に重量なことは演算です。演算とは一般数学の足す、引く、掛ける、分ける計算と同じです。 でも、プログラムは単純な数学の計算だけではなく、ビットの計算、論理計算もあります。 演算子 使用方法 説明 算術演算子 + a + b 足す - a - b 引く * a * b 掛ける / a / b 分ける % a % b 分けるのあまり ++ ++a, a++ 値を1を増加する。(前位、後位演算子) -- --a, a-- 値を1を減少する。(前位、後位演算子) 関係演算子 > a > b aがbより大きいならtrueを返却、小さいや同じならfalseを返却 >= a >= b aがbより大きいか同じならtrueを返却、小さいならfalseを返却 < a < b aがbより小さいならtrueを返却、大きいか同じならfalseを返却 <= a <= b aがbより小さいか同じならtrueを返却、大きいならfalseを返却 == a == b aとb同じならtrueを返却、違いならfalseを返却 != a != b aとbが違いならtrueを返却、同じならtrueを返却 ビット演算子 << a << b 整数aの2進数値を左にb程移

Study / C#

#C#

作成日付 : 2019/07/04 00:09:43       修正日付 : 2021/07/12 19:56:09

57

こんにちは。明月です。この投稿はデータタイプ変換(キャスト:cast)とコメント(comment)に関する説明です。データタイプ変換(キャスト:cast)以前の投稿でデータタイプに関して説明しました。link - [c#] 04. データタイプとリテラル(literal)、 nullableプログラムで我々がすべてのデータタイプを合わせてデータを入力するし、その入力データにより計算することはできません。例えば、我々はプログラムで実数のデータと整数のデータを受け取りました。上の例は整数タイプのa変数と実数タイプのb変数の値を足して整数タイプのcの変数に格納したいです。デバッグでデータタイプが違うというエラーが発生します。そうすると我々は実数タイプ(float)のデータを整数タイプ(int)に変換しなければならないです。そのことをデータイプ変換、つまりキャスト(cast)と言います。実数から整数、整数から実数の変換はただ括弧でキャストが可能です。この括弧でキャストすることは数のデータタイプだけです。つまり、整数タイプから実数タイプ、実数タイプから整数タイプだけです。そうなら数タイプではない文字列(string)タイプはどうでしょう。int32クラスのparse関数を利用すればキャストが可能です。parse関数はstringタイプだけではなく、実数タイプ(float、double)のキャストも可能です。改めてまとめると、キャストする時には数の関係なデータは括弧でキャストが可能ですが、確実にキャストをするためにはint32クラスのparse関数を利用する方が良いです。また、文字列のタイプをキャストする時に文字列に数字だけあることではないです。文字がある可能性もありますね。実行中でエラーが発生します。当たり前の話ですが、文字は数字に変換ができないのでエラーが発生しますね。でも、プログラム中でデータが間違いにある可能性があるので、エラーを発生することよりキャストができないデータならデータデフォルト値(0)に設定する方法があります。上の例は各データタイプのクラスを利用してキャストしました。c#にはキャスト専用クラスがあります。convertクラスの場合はキャスト専用クラスです。つまり、実数から整数、文字列から整数などをキャストする関数があります。 メソッド 説明 boo

Study / C#

#C#

作成日付 : 2019/07/04 00:01:12       修正日付 : 2021/07/09 19:49:31

59

こんにちは。明月です。この投稿はプログラミングの始めと変数と定数を使う方法に関する説明です。c#で一つのプログラムを作成しようと思えば基本的にクラスと関数、ライブラリを知らなければならないです。上のソースをvisual stuioツールを利用して作成してf5を押下してビルド及び実行すれば下記通りの結果が表示されます。そのことで任意のキーを押下するとプログラムを終了になります。上の例だけ確認しても基本的にnamespaceの中でprogramというクラスがあります。また、クラスの中ではmainという関数があります。main関数にはstring[]タイプになっているパラメータがあるし、staticとvoidのキーワードで関数を定義しています。namespaceとクラス、関数は中括弧({})でその領域を定義しているし、main関数にはconsoleクラスのwritelineとreadkeyの関数を使っています。上のプログラムを開始するとコンソールで動きますが、consoleクラスはコンソールウィンドウで作動するライブラリです。つまり、writeline関数はコンソールウィンドウで文字を出力する関数、readkeyはユーザからキーボードデータを入力値を受け取る関数です。上の形がc#のプログラム基本形式です。それならこれからプログラムを作成しましょう。我々がプログラムを作成すれば一番扱うキーワードは変数と定数です。プログラムを簡単に定義すると高性能な計算機です。つまり、1+1や1+2を計算する計算機です。この計算機は計算した値を何処かで格納することができますが、それが変数です。上の例は1+1の結果値をaという変数に格納しました。aという変数の前にはintというデータタイプキーワードを宣言しました。つまり、変数宣言はデータタープと変数名で宣言することができます。そしてbという変数には1+2の結果値を格納しました。また、consoleクラスのwriteline関数を利用してコンソールに出力しました。ここで""のマークで書いている文字列はそのままにコンソールに出力されます。その後で+aを入れてaの変数に格納された値が出力します。変数の値は数を計算して格納する機能をありますが、変数と変数の計算して格納することもできます。予想とおりにcの値は5が出力しました。変数は数を計算して値を格納し、その値を修正する

Study / C#

#C#

作成日付 : 2019/07/02 23:46:49       修正日付 : 2021/07/07 14:24:45

60

こんにちは。明月です。この投稿はvisual studioをインストールする方法に関する説明です。c#で開発するためには一応、開発ツール(ide)をインストールしなければならないです。c#の開発ツールはjavaみたいに様々があることではなく、visual studioで決まっています。もちろん、メモ帳で作成してビルドファイルを利用して開発することもできますが、visual studioが値段が高いプログラムでもないし、無料ツールなのでただダウンロードして使ったらよいです。(会社で商業的に開発することはライセンス値段が必要です。)visual studioはパソコンの高いスペックが必要です。なので、開発準備する前にパソコンのスペックをアップグレードしましょう。visual studioをダウンロードしてインストールしましょう。link - https://visualstudio.microsoft.com/ja/vs/visual studioのバージョンでprofessionalとenterpriseがあります。そのバージョンは無料ではないので、我々はcommunityバージョンを使いましょう。その後でインストールファイルをクリックして実行すればインストールに必要なファイルを先にインストールするということにメッセージが表示されます。そのままにインストールしましょう。インストールが終わったらインストールオプションメニューが表示されます。我々は一応、たくさんの機能が必要ないのでasp.netとpython、.net desktop、c++だけ選択してインストールしましょう。インストールした後には必要なコンポーネントがあれば追加インストールができるので、始めは必ず必要なことだけインストールしましょう。(時間がたくさんかかります。)インストールが完了するとログインするメニューが表示されます。microsoftのidを入れてログインすればよいです。(もし、idがなければ会員登録しましょう。登録で別に料金がかかることではありません。ログインしないとcommunityバージョンでも30日しか使えません。)ログインしたらプロジェクト選択画面が表示されます。一応、しっかりインストールされたかを確認するためにcreate new projectを選択しましょう。そしてc#コンソールプロジェクトを選択しましょう。ここでcor

Study / C#

#C#

作成日付 : 2019/07/01 23:58:20       修正日付 : 2021/07/06 20:04:50

61

こんにちは。明月です。この投稿はc#とはに関する説明です。プログラム言語はc、c++、java、c#など様々な言語があります。言語の誕生時期はc言語が一番早いし、次はmicrosoftからウィンドウ開発をしやすくするc++(mfc)、プログラムについて少し知ってる方なら一回ごろは聞いたことがある言語のjava、これから説明しようと思うc#の順になります。誕生時期を見るとc#は上の4つの言語の中で最後になりますが、最後に誕生したから一番いい言語だと思いますが、そうではありません。プログラム言語は各特徴があり、開発状況のたびに使う方法が違います。各言語について簡単に説明するとc言語の場合はハードウェア系とos系(カーネル)、ドライバー系で主に開発するし、c++(mfc)はグラフィック系またはc#で実装が大変な部分、c#よりメモリ管理が厳しい環境で使います。javaの場合はネットワークのウェブ系、アンドロイドモバイル系で使うし、c#はネットワークサーバクライアントウィンドウ(cs)系でよく使います。機能として使うところはそのとおりですが、プロジェクトの予算、環境などの影響でウィンドウプログラムをjavaで開発するし、c++とc#を混在して使う時もあります。でもその特徴で必ずjavaはウェブ、c#はウィンドウフォームで開発することではありません。ただ、仕様の状況、環境の設定により影響がたくさんあるので、何がよいか悪いかを決めることではありません。c#というプログラムは.net frameworkの上で動いています。.netframeworkはウィンドウosしかないのでlinuxやウィンドウ以外の環境では開発ができません。(最近はコアー(core)というlinuxライブラリもありますが、一般的な状況じゃありません。)フレームワークとはc言語みたいに開発の環境によりすべてを開発することではなく、基本的なライブラリや基盤に関してはフレームワークにすべて開発しているので、c#にはapiとして取得して使う形で開発します。それをclr(common language runtime)といいます。clr(common language runtime)とは.net系の言語(vb.net、c#.net、c++.netなど)の仮想マシンの構成要素です。仮想マシンとはプログラムのメモリ管理(インスタンス生成及び解除)するし、様々なコ

Study / C#

#C#

作成日付 : 2019/07/01 23:32:22       修正日付 : 2021/07/06 19:24:19