- 投稿日:2021-03-29T21:50:44+09:00
【C#】staticっていつ使えばいいの?何がいいの?
staticいつ使えばいいんですか?
積極的に使う気が起きなかったが、上司のソースコードを見ると各所に散見されたので
いつ使えばいいのか?どんなメリットがあるのか?という観点で調べた。
1. staticとは
2. staticは何がいいのか
3. staticの良くないところ
4. いつ使えば良いのか
5. staticの書き方
6. まとめ
7. 参照1. staticとは
- 修飾子。
- 静的クラス・メンバーの宣言で使う。
- 静的クラスの場合メンバーも静的にする。
- 静的クラスの場合コンストラクターを含めることはできない。
- メモリを静的に確保する。
メンバ変数にstaticをつけた場合、その変数がメモリ上のどこに配置されるかが固定される。
メモリ上の位置が固定されるということはどこからでもこの変数にアクセスできるということです。
[https://qiita.com/suin/items/0897adc7dc653b9c20de]2. staticは何がいいのか
- インスタンス化するより処理が早くなる。というかインスタンス化は相対的にメモリを圧迫する。
インスタンスメンバーが追加されない保証がされる。
「静的クラスを使用する利点は、インスタンス メンバーが誤って追加されないことをコンパイラで確認できるという点です。
コンパイラによって、このクラスのインスタンスを作成できないことが保証されます。」staticにするとインスタンス参照せずに直でメンバーへアクセスできる。
クラス唯一のものであればstaticとするという使い方ができる。
下記のPersonクラスではnameやageはPerson毎に変わるが、scientifiName(学名)は必ずホモサピエンスとなるのでstaticとしている。これによりインスタンス化されて
例)
class Person { public string name; // インスタンス化したPersonごとに変わる。 public int age; // 同上。 public static string scientificName;// インスタンス化してもPersonは皆ホモサピエンスで変わらない。 } Person p = new Person() p.name = "安倍 晋三"; p.age = 66; Person.scientificName = "Homo Sapiens";3. staticの良くないところ
どのクラスからでもアクセスできてしまう為副作用が起こりうる。
(副作用:関数が終了した後に影響が残ること。この場合呼び出され値を変更されるなど。)Singletonパターンを採用した方がいいケース
同様の質疑がありました。
そもそもSingletonパターンとは
[C#]Singletonパターン実装方法(備忘録
C# での Singleton についてまとめ4. いつ使えば良いのか
- 共通のメソッドを定義する場合
- 共通のプロパティを定義する場合
- 複数クラス間で共通のプロパティを共有したい場合
とは言え、副作用を考えると極力使いたくないしオブジェクト指向的でないと思います。
しかし、上記例のようにクラス唯一の変数であり、5. staticの書き方
static 型名 フィールド名 // 例 public class MyBaseC { public struct MyStruct { public static int x = 100; } }クラスをstaticにした場合はスコープ内のメンバーもstaticとしなければならない。
アクセスする方法
- 完全修飾名 (
MyBaseC.MyStruct.x
) を使用。 (同じスコープからその静的メンバーにアクセス可能でない限り) ##### これはできない- 静的なローカル変数化 (つまり、メソッドのスコープで宣言された変数) 。
6. まとめ
静的メンバーはアプリケーション起動時にメモリを確保し
、終了までメモリの割り当てが変更されない。
故にどこからでもアクセスできるようになる。共通して使うメソッドや、クラス内で唯一の変数などに使う。
メソッドは特別staticにする利点は見つからなかった。変数はインスタンス化することで、本来一つしかないはずの情報が複数作られるのを防ぐことができる。しかし、副作用があるため代替方法があるなら検討すべき。
間違いやツッコミあったら教えてください?
7. 参照
静的クラスと静的クラス メンバー
PHP: 静的メソッドは何のためにあるか?
わい、static変数とstaticメソッドについて熱く語る
プログラミング序論 11.記憶クラスとスコープ
- 投稿日:2021-03-29T21:50:44+09:00
staticっていつ使えばいいの?何がいいの?
staticいつ使えばいいんですか?
積極的に使う気が起きなかったが、上司のソースコードを見ると各所に散見されたので
いつ使えばいいのか?どんなメリットがあるのか?という観点で調べた。
1. staticとは
2. staticは何がいいのか
3. staticの良くないところ
4. いつ使えば良いのか
5. staticの書き方
6. まとめ
7. 参照1. staticとは
- 修飾子。
- 静的クラス・メンバーの宣言で使う。
- 静的クラスの場合メンバーも静的にする。
- 静的クラスの場合コンストラクターを含めることはできない。
- メモリを静的に確保する。
メンバ変数にstaticをつけた場合、その変数がメモリ上のどこに配置されるかが固定される。
メモリ上の位置が固定されるということはどこからでもこの変数にアクセスできるということです。
[https://qiita.com/suin/items/0897adc7dc653b9c20de]2. staticは何がいいのか
- インスタンス化するより処理が早くなる。というかインスタンス化は相対的にメモリを圧迫する。
インスタンスメンバーが追加されない保証がされる。
「静的クラスを使用する利点は、インスタンス メンバーが誤って追加されないことをコンパイラで確認できるという点です。
コンパイラによって、このクラスのインスタンスを作成できないことが保証されます。」staticにするとインスタンス参照せずに直でメンバーへアクセスできる。
クラス唯一のものであればstaticとするという使い方ができる。
下記のPersonクラスではnameやageはPerson毎に変わるが、scientifiName(学名)は必ずホモサピエンスとなるのでstaticとしている。これによりインスタンス化されて
例)
class Person { public string name; // インスタンス化したPersonごとに変わる。 public int age; // 同上。 public static string scientificName;// インスタンス化してもPersonは皆ホモサピエンスで変わらない。 } Person p = new Person() p.name = "安倍 晋三"; p.age = 66; Person.scientificName = "Homo Sapiens";3. staticの良くないところ
どのクラスからでもアクセスできてしまう為副作用が起こりうる。
(副作用:関数が終了した後に影響が残ること。この場合呼び出され値を変更されるなど。)Singletonパターンを採用した方がいいケース
同様の質疑がありました。
そもそもSingletonパターンとは
[C#]Singletonパターン実装方法(備忘録
C# での Singleton についてまとめ4. いつ使えば良いのか
- 共通のメソッドを定義する場合
- 共通のプロパティを定義する場合
- 複数クラス間で共通のプロパティを共有したい場合
とは言え、副作用を考えると極力使いたくないしオブジェクト指向的でないと思います。
しかし、上記例のようにクラス唯一の変数であり、5. staticの書き方
static 型名 フィールド名 // 例 public class MyBaseC { public struct MyStruct { public static int x = 100; } }クラスをstaticにした場合はスコープ内のメンバーもstaticとしなければならない。
アクセスする方法
- 完全修飾名 (
MyBaseC.MyStruct.x
) を使用。 (同じスコープからその静的メンバーにアクセス可能でない限り) ##### これはできない- 静的なローカル変数化 (つまり、メソッドのスコープで宣言された変数) 。
6. まとめ
静的メンバーはアプリケーション起動時にメモリを確保し
、終了までメモリの割り当てが変更されない。
故にどこからでもアクセスできるようになる。共通して使うメソッドや、クラス内で唯一の変数などに使う。
メソッドは特別staticにする利点は見つからなかった。変数はインスタンス化することで、本来一つしかないはずの情報が複数作られるのを防ぐことができる。しかし、副作用があるため代替方法があるなら検討すべき。
間違いやツッコミあったら教えてください?
7. 参照
静的クラスと静的クラス メンバー
PHP: 静的メソッドは何のためにあるか?
わい、static変数とstaticメソッドについて熱く語る
プログラミング序論 11.記憶クラスとスコープ
- 投稿日:2021-03-29T20:05:34+09:00
[c#]preview言語バージョンを使う方法
- 投稿日:2021-03-29T16:36:16+09:00
[C#] TCPサーバープログラムを作成する
TCPサーバーを C# で構築したかったが、C#フォームアプリケーションから使いやすい形式のものが無かったので、dobon.net さんの下記記事をベースに改編した。
https://dobon.net/vb/dotnet/internet/tcpclientserver.html
スレッドではなくタイマつかってるのでご注意。ClassTcpServer.csnamespace TcpServer { // 使い方 //宣言 //TcpServer.ClassTcpServer classTcpServer = new TcpServer.ClassTcpServer(); // 初期化、スタート // classTcpServer.ipaddress = "0.0.0.0"; // classTcpServer.port = 49152; // classTcpServer.timerinterval = 100; // classTcpServer.DataReceived += new TcpServer.ClassTcpServer.DataReceivedEventHandler(TcpServer_DataReceived); // classTcpServer.Start(); // 停止 // classTcpServer.Stop(); // イベントハンドラ //private void TcpServer_DataReceived(object sender, TcpServer.DataReceivedEventArgs e) //{ // //イベントが発生したとき // textBox1.AppendText(e.Message + Environment.NewLine); //} public class DataReceivedEventArgs : EventArgs { public string Message; } class ClassTcpServer { public string ipaddress { get; set; } public int port { get; set; } public int timerinterval { get; set; } private System.Net.Sockets.TcpListener listener; private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); public delegate void DataReceivedEventHandler(object sender, DataReceivedEventArgs e); public event DataReceivedEventHandler DataReceived; public ClassTcpServer() { } public void Start() { //TcpListenerオブジェクトを作成する listener = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Parse(ipaddress), port); //Listenを開始する listener.Start(); // タイマスタート timer.Interval = timerinterval; timer.Tick += new EventHandler(timer_Tick); timer.Start(); } public void Stop() { // タイマストップ timer.Stop(); if (listener != null) { //リスナを閉じる listener.Stop(); } listener = null; } private void timer_Tick(object sender, EventArgs e) { //接続要求が無かったら return if (!listener.Pending()) { return; } //接続要求があったら受け入れる System.Net.Sockets.TcpClient client = listener.AcceptTcpClient(); //NetworkStreamを取得 System.Net.Sockets.NetworkStream ns = client.GetStream(); //読み取り、書き込みのタイムアウト //デフォルトはInfiniteで、タイムアウトしない //(.NET Framework 2.0以上が必要) ns.ReadTimeout = 10000; ns.WriteTimeout = 10000; //クライアントから送られたデータを受信する System.Text.Encoding enc = System.Text.Encoding.UTF8; bool disconnected = false; System.IO.MemoryStream ms = new System.IO.MemoryStream(); byte[] resBytes = new byte[256]; int resSize = 0; do { //データの一部を受信する resSize = ns.Read(resBytes, 0, resBytes.Length); //Readが0を返した時はクライアントが切断したと判断 if (resSize == 0) { disconnected = true; break; } //受信したデータを蓄積する ms.Write(resBytes, 0, resSize); //まだ読み取れるデータがあるか、データの最後が\nでない時は、 // 受信を続ける } while (ns.DataAvailable || resBytes[resSize - 1] != '\n'); //受信したデータを文字列に変換 string resMsg = enc.GetString(ms.GetBuffer(), 0, (int)ms.Length); ms.Close(); //末尾の\nを削除 resMsg = resMsg.TrimEnd('\n'); // イベント発生して呼び出し元にデータを返す DataReceivedEventArgs ee = new DataReceivedEventArgs(); ee.Message = resMsg; DataReceived(this, ee); if (!disconnected) { //クライアントにデータを送信する //クライアントに送信する文字列を作成 string sendMsg = resMsg.Length.ToString(); //文字列をByte型配列に変換 byte[] sendBytes = enc.GetBytes(sendMsg + '\n'); //データを送信する ns.Write(sendBytes, 0, sendBytes.Length); } //閉じる ns.Close(); client.Close(); } } }
- 投稿日:2021-03-29T15:42:03+09:00
Ubuntu上でC言語やC#を各種エディタで書いてみる
Linuxは、狭義にはLinuxカーネル、広義にはそれをカーネルとして用いたオペレーティングシステムを指します。LinuxはUnix系オペレーティングシステム (OS) の1つと言えます。
UbuntuはLinuxディストリビューションの1つです。初心者からベテランまで、幅広く利用されています。本稿では、C言語やC#のプログラムを各種エディタを用いて作成します。
参考URL
VirtualBox上にUbuntu 20.04をインストールする方法は、以下のリンクが参考になると思います。
プログラマーのためのUbuntuC言語のコンパイル環境を構築しよう
端末を起動し、以下を実行します。
sudo apt update sudo apt install build-essentialgeditでC言語を編集してみる
geditはUbuntu標準のエディタで、初心者向けと言えます。ディスクトップ最上段の「アクティビティ」をクリックし、「ged」と入力してgeditを起動します。
まず、geditの下の「なし」をクリックし、メニューから「C」を選択します。そして次のコードを入力します。
sample01.c#include <stdlib.h> int main() { system("/bin/cat /etc/lsb-release"); }すると、エディタ上のコードはシンタックスハイライトされて表示されます。
次に、gedit上部の保存ボタンをクリックし、「sample01.c」として保存します。そして次のコマンドでコンパイルし、実行してみます。gcc -o sample01 sample01.c ./sample01
下記のように、Ubuntuのバージョン情報が表示されれば成功です。
実行結果DISTRIB_ID=Ubuntu DISTRIB_RELEASE=20.04 DISTRIB_CODENAME=focal DISTRIB_DESCRIPTION=”Ubuntu 20.04 LTS”C#の編集と実行に挑戦してみる
まず、C#をインストールします。
C#のインストールsudo apt install mono-devel今度はnanoというエディタを使ってみます。nanoはGUIを持たない、CUIベースのエディタです。リモートログインして作業するなど、GUIが使用できない環境でも使用できる利点があります。
nanoの起動nano sample02.cs以下のコードを入力します。
sample02.csusing System; using System.IO; using System.Text; class FileRead1 { static void Main() { StreamReader sr = new StreamReader( "/etc/lsb-release"); string text = sr.ReadToEnd(); sr.Close(); Console.Write(text); } }Ctrl+Oで”sample02.cs”という名称でファイルに書き込みます。次にCtrl+Xで終了します。nanoを終了したら、コンパイルします。
C#のコンパイルmcs sample02.csコンパイルが完了すると、”sample02.exe”というファイルが生成されています。”sample02.exe”を実行してみてください。
sample02の実行./sample02.exe先ほどのC言語のプログラムと同じ、Ubuntuのバージョン情報が出力されます。
Visual Studio Codeのインストール
最後に、人気のVisual Studio Codeのインストール方法を紹介します。Ubuntu20.04ではsnapを用いてインストールできます。
VScodeのインストールsudo snap install --classic code codeさいごに
Windows10の環境であれば、WSL(Windows Subusystem for Linux)のUbuntuから実行するのが手っ取り早いでしょう。
WSLのUbuntuを構築する方法は、よければ以下のリンクを参考にしてみてください。
- 投稿日:2021-03-29T14:52:14+09:00
【C#⇔C++/CLI】ファイルまたはアセンブリ、またはその依存関係の1つが読めませんでした。【トラブルシューティング】
概要
Windows専用のアプリケーションなんて今更・・・という昨今ですが、
未だに.NET Frameworkや.NET Coreで、C++のコードとC#のコードをまとめて使うときにC++/CLIというMicrosoftが開発した中間言語を使って、ネイティブコードを共存させたいという需要が狭い世界で存在します。
C++/CLIは、現状C++用のラッパーとしてDLLとして作成する場合での運用でのみ、Microsoftからも推奨されています。
そして、.NET FrameworkのC++/CLIの設定を誤ると、表題のエラーを見かけるようになります。
この狭い世界で何度か開発することがあったので、C++/CLI導入時のチェックリストみたいなのを用意しておこうと思います。
Windows Forms, WPF, UWPの場合
C++/CLIで結合されているオブジェクトを参照すると、こんな感じのエラーが出てきます。
チェックするべき項目
実行ファイル側が"Any CPU"になっていないこと
実行されるDLLと実行ファイル側が"x86/Win32"または"x64"に統一されていること
基本的に、C++/CLIで作成されたDLLは、32bitで使用するか64bitで使用するかを指定する必要があります。
両方のCPUで使えるような器用な仕様にはなっていません。
従って、上のように"Any CPU"という設定が混在している場合は、"x86/Win32"または"x64"に設定を統一しましょう。実行予定のDLLが、全く同じディレクトリに含まれていること
① C++/CLI以外に、C++ネイティブDLLが混在する場合は、ビルド時に自動的に実行ファイルのディレクトリ下に保存してくれません。
その場合は、ビルドイベントを使って、dllファイル、pdbファイルをコピーするようにしましょう。
(pdbファイルを入れ忘れると、ネイティブコードのデバッグが出来なくなるので注意すること。)② もし依存関係が分からない場合は、Dependenciesをダウンロードして調べると、一目で理解できます。
ASP .NETの場合
ローカルサーバを立てた場合のデバッガの挙動
大体こんな感じの画面になります。チェックするべき項目
基本的には、上記のケースと同じですが、これ以外に下記の内容も確認しましょう。
IIS Expressが32ビット版、64ビット版に統一されているかを確認する
ツール>オプション>プロジェクトおよびソリューションを参照
64bitのC++/CLIのDLLを使用する場合は、Webサイトおよびプロジェクト用IIS Expressの64ビットバージョンを使用するにチェックを入れます。
- 投稿日:2021-03-29T13:35:57+09:00
Html.ActionLinkを使うとhrefに「?Length=4」がついてしまう
起こったこと
Viewで@Html.ActionLinkを使ってaタグを作成すると、hrefに「?Length=4」がついてしまう。
CSHTML@Html.ActionLink("About", "About", "Home", new { @class = "btn btn-primary" })原因
コントローラーを直で書いているのが原因みたい。
string routeValuesのオブジェクト「Home」を取得します。MVCはこれをパブリックプロパティを検索してルート値に変換します。stringオブジェクトの場合、唯一のパブリックプロパティはLengthであり、Lengthパラメータでルートが定義されないため、プロパティ名と値がクエリ文字列パラメータとして追加されます。
対処
string controllerNameにべた書きせずにstring routeValuesに設定する。
CSHTML@Html.ActionLink("About", "About", new { controller = "Home" }, new { @class = "btn btn-primary" })