質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。

Q&A

解決済

4回答

2205閲覧

C# クラスについて

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。

0グッド

1クリップ

投稿2018/04/13 12:36

現在C#の勉強を少し前から始め、
フォームアプリを使いチャットやソケット通信などをしております。

クラスやオブジェクト継承などについて
最初に軽く勉強はしたのですが(とは言っても、こんな感じかぁ...程度です)
実際にコードを書いていくうちに、
ひとつのクラスがメソッドだらけでとても長く見づらいものとなってしまいました。

そこでこれから先、もし同じようなプログラムを組むときに、
使い回し等が効くようにクラス分けしたいと思いました。

例えば今やっているシリアル通信で、
1.今回のアプリで使う具体的な数値や設定
2.使い回しのきく、送受信の処理
3.使い回しのきく、COMポートをOPENする処理
4.メッセージボックスにて使う処理
のようにクラス分けするのかな?という考えに現在至っているわけですが、
相違があれば教えていただきたいです。

また、使い回す際のコードの書き方がいまいちわからないです。
例えば、

C#

1 recData += System.Text.Encoding.ASCII.GetString(buffer); 2 var temporary = Sendbuffa + recData; 3 while (true) 4 { 5 newline = temporary.IndexOf(Environment.NewLine); 6 if (newline >= 0) 7 { 8 string[] lines = temporary.Split( 9 new[] { Environment.NewLine }, 10 StringSplitOptions.None 11 ); 12 logText(lines[0], ComPort); 13 14 if (lines.Length > 1) 15 { 16 // temporaryに残りを詰めなおす 17 temporary = temporary.Substring(newline + 2); 18 } 19 } 20 else 21 { 22 Sendbuffa = temporary; //データをいったん保存 23 break; 24 } 25 }

このコード(前回質問させていただいた時の教えていただいたコードなのですが...)を
使い回しのきくクラスとメインの今回のアプリで使うクラスに分けるには、
どのようにすればいいのでしょうか?

気をつける点やポイント等教えていただきたいです。
長くなりましたがよろしくお願いいたします。

[++C++;//未確認飛行C]
http://ufcpp.net/study/csharp/oo_class.html
こちらのサイトも参考にさせていただいたのですが自分の知識がついてこず..
いまいちピンと来てくれませんでした :(

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

このコードに使いまわせる部分は無いと思います。

###追記

使いまわすならこんな風に書きます。

C#

1public static IEnumerable<string> SplitLines(byte[] buffer, Encoding encoding) 2{ 3 using (var reader = new StringReader(encoding.GetString(buffer))) 4 { 5 while (true) 6 { 7 string result = reader.ReadLine(); 8 if (result == null) break; 9 yield return result; 10 } 11 } 12}

もっと簡単にこうも書けます。Encoding は省いて文字列対象にしました。
バイトデータから文字列を取り出すのは上記のように簡単なので。

C#

1static IEnumerable<string> SplitLines(string str) 2{ 3 return Regex.Split(str, "\r?\n"); 4}

投稿2018/04/13 13:59

編集2018/04/13 22:41
Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/04/15 10:30

コメントありがとうございます。 こんなにコードが簡潔でとても見やすくなるんですね!! 参考にさせていただきます!
guest

0

通信部分に関してはよくわからなかったのですが、要は区切り文字毎にLogに書き出すという内容と理解しました。

であれば、そのように書くのがオブジェクト指向の醍醐味です。

再利用性はあまり考えない方がクラス分けはしやすいです。
例えばこんなのはどうでしょうか?
(あくまで例です。雰囲気をつかんでもらえれば・・・)

c#

1var receiver = new XXRciver(env); 2receiver.Receive((string line) => {logText(lines[0], ComPort);});

1行目は、動作に関して初期値を与えています。
引数は一つになっていますが、実際はたくさんあったり、それをまとめたクラスだったりを入れます。

XXRciverの中身はクラスの設計時には気にしないようにしてください。

2行目は、受信時の動作を定義しています。
レシーバーは受信するのが目的のオブジェクトです。
受信した後の動作は、外部から指定してあげる必要があります。
ループの内側にある部分なので、処理を渡してます。

ラムダ式に慣れていないなら、インターフェイス越しに書きこんでもいいです。
(このインターフェイスは再利用のためというわけではなく、受け取り側がどのメソッドを気にして、どのメソッドを気にしていないのかを宣言するためのものです。場合によっては不要です。)

C#

1interface IAtRecieved{ 2 void AtRecieved(string line); 3} 4 5class LogWriter : IAtRecieved{ 6 void AtRecieved(){ 7 logText(lines[0], ComPort); 8 } 9}

このように関心事を明確にして、簡潔に記述し段階を分けることを主眼としてください。

適切に分割されていれば、再利用が可能が場合もあると思います。

再利用を目的として書くとどうしても”かもしれない”で余分な機能を作りこみます。しかし、大体において予想外の機能が必要になるため、余分な機能がてんこ盛りのクラスの変更が大変だということになりますのでご注意を。関心事ごとに分割されているのが大事です。

投稿2018/04/14 02:26

iwamoto_takaaki

総合スコア2883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/04/15 01:37

コメントありがとうございます。 おっしゃる通り再利用のことばかり考えておりました。。 これからは、事柄ごとに分割してすっきり見やすいコードかけるように頑張ります!
guest

0

別解をひとつ。

前の質問で、バイナリ通信にこだわられてたようなので、

  • バイナリ受信クラス

バイナリデータ列をリングバッファやStreamかなんかで保持
バイナリデータによりIndexOfメソッド、
先頭からnバイト取得/削除するメソッド

  • バイナリデータを文字列に変換するクラス

おそらくStringBuilderあたりをつかって、
バイナリ受信クラスに改行コードのバイト文字列を与えて先頭データ列を取得、文字列に変換して返す
存在する行を全部string配列/Enumerableにして返すメソッド

まあ、こういうふうに分ければ、バイナリ通信の場合に使いまわしできるし、バイナリ-文字列変換ってのも他に使いまわしできるように思います

#再利用できるように、ちとムリクリですがw

投稿2018/04/14 03:30

y_waiwai

総合スコア87749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/04/15 01:26

なるほど。結構細かく分けるのですね! やっと少しは分け方がわかって来た気がします。 用途ごとややっていることの種類が同じようなことをまとめてクラス分けのような感じで徐々にできるようになります! ありがとうございます!!
guest

0

ベストアンサー

a. コードで気になった点。
1, 受信処理の解析と思われる部分に変数名:Sendbuffaがあるのが気になります。
送受信データの混在を避けるため送信バッファ/受信バッファの変数は分けると思いますが、単純に変数名の命名がそうなっていただけでしょうか?

C#

1var temporary = Sendbuffa + recData;

2,temporary.IndexOftemporary.Splitを同時に行っているのが気になります。
whileループからforループに変換して、以下のコードでも。

C#

1var temporary = Sendbuffa + recData; 2var lines = temporary.Split(new[] { Environment.NewLine }, 3 StringSplitOptions.None 4 ); 5for (int i=0; i< lines.Length - 1; i++) 6{ 7 logText(lines[i], ComPort); 8} 9Sendbuffa = lines.Last();

3,デミリタ(区切り文字)にEnvironment.NewLineを使っている点
参考 ->environment.newline

UNIX 以外のプラットフォームでは "\r\n" を含む文字列。UNIX プラットフォームでは "\n" を含む文字列。

Unixプラットフォームではenvironment.newlineの改行コードが違うため、このプログラムをUnixで動かした時に注意が必要です。


b. クラス分けについて
SerialPortServerクラスを新規作成して、2)と3)の処理を行います。

4)はクラスを作らずにAction<string>SerialPortServerクラスに定義します。
参考 -> Action<T> デリゲート

C#

1public Action<string> logWrite;

呼び出し方
logWrite(lines[0]);

画面を更新する必要がある時は、Actionイベント内でコントロール名.Dispatcher.BeginInvoke();を呼び出すのをお忘れなく。

最後に通信に関わる部分は通信プロトコル解析処理(Parser)がどうしても必要になるので、使い回しはしずらいと思いますー。
自作せずにHTTPなどのプロトコルを上に被せる形がいいのではと。
どうしても自作するなら、状態遷移図と通信プロトコルのドキュメントは最初に作成するほうが後々苦労しないです。

投稿2018/04/13 15:58

編集2018/04/13 19:52
umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/04/16 00:37 編集

コメントありがとうございます! まずバッファ変数名については、自分の命名が下手でした。。 「送られて来た」ということでsendにしていましたが、今考えると変ですね。。。 まだプログラミング勉強し始めたばかりで、C言語C++そしてC#の順に勉強しており、「これからのことを考えてこうするといいよ。」というのは本当に助かります!(やっぱりやるからにはこれからの事を見据えた勉強をしていきたいと思っておりますので : ) ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問