C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

共通関数にする為のロジック?


(過去ログ 5 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■5999 / inTopicNo.1)  共通関数にする為のロジック?
  
□投稿者/ tomoko 二等兵(1回)-(2006/08/26(Sat) 03:55:43)

分類:[C#] 


分類:[C#] 

私は今C#でプログラムを作成しているのですが、
なかなか共通関数をうまく作れません。
下記のものを共通でうまくまとめたいと思っております。
ーーーーーーーーーーーーーーーーーー
public class TestInfo
{
  private string _code1;
  private string _code2;

  public static readonly int code1Count = 3;
  public static readonly int code2Count = 4;
  public static readonly int countSum = code1Count + code2Count;

  public string Code1
  {
    get { return _code1; }
    set { _code1 = value; }
  }

  public string Code2
  {
    get { return _code2; }
    set { _code2 = value; }
  }
}
ーーーーーーーーーーーーーーーーーー
class Test{
//〜〜
  public void TestFileTorikomi()
  {
  //〜〜

    //ここから↓をまとめたい
    using (StreamReader streamReader = new StreamReader(_filePath))
    {
      string allData = streamReader.ReadToEnd();

      TestInfo testInfo = new TestInfo();

      int i = 1;
      int index = 0;
      while (allData.Length / TestInfo.countSum >= i)
      {
        testInfo.Code1 = allData.Substring(index, TestInfo.code1Count);
        index = index + TestInfo.code1Count;//ここが無くなってスッキリ?
        testInfo.Code2 = allData.Substring(index, TestInfo.code2Count);
        index = index + TestInfo.code2Count;//ここが無くなってスッキリ?
        i++;
//ここからは↓はtestInfoを色々と使って処理
        //例えば、commonDataSyori.update(testInfo);
      }
    }
  }
}

上記の処理は、ファイルのデータを3バイト、4バイトとデータを取り、そのデータをTestInfoに代入するといった事をしようとしています。
その後、TestInfoで色々と処理をしようとしています。
例えば、「123ABCD456EFGH」というデータがファイルにあれば、
1回目のループでcode1=123,code2=ABCD
2回目のループでcode1=456,code2=EFGH
と値が取れ、最後はループを抜けて終了です。
始めは、いろいろとファイルを扱った処理はCommonFileクラスというものを作りまとめていました。
CommonFileクラス側にTestInfo.code1CountあるいはTestInfo.code2Countさえ渡せば、
CommonFileクラス側でSubstringをし、文字を切り取って、stringのデータ(123)を返すメソッドを作っていました。
結局、何が便利かというと、「index = index + TestInfo.code1Count」のindexを増やす場所がCommonFile側に置いていたので、indexを数えなくても良いという共通メソッドです。
自分としてはスッキリしたと思っていたのですが、周りからは批判。
共通に置くまでも無いような共通メソッドと言われました。
ただ単にindexを他の方が書くか?共通が数えるか?程度だったので・・・。
よって、結局は上記のようにクラス側で、indexを数えています。
理想は、TestInfoさえ渡せば、Code1,2に値がセットされて、TestInfoが帰ってくるのが理想であると言われました。
testInfo = common.cut(testInfo);←こんな感じ?
しかし、私には上記のプログラムをスッキリさせる方法が分かりません。
この事があってから、デザインパターンの本を買ったりして勉強を始めたのですが、
その本を理解するのでもう必死という感じです。
上記のプログラムを共通クラスでスッキリさせるにはどうすればいいでしょうか?
特に例に挙げたものでも無くてもよいので、こんな共通メソッドが良いとかこのメソッドを使ってみては?
とか何でも良いので何か思った方はアドバイス下さい。
よろしくお願いします。
(C#の事では無く、ロジックよりでスミマセン)

0
引用返信 編集キー/
■6011 / inTopicNo.2)  Re[1]: 共通関数にする為のロジック?
□投稿者/ ひろえむ 二等兵(2回)-(2006/08/26(Sat) 08:21:02)
ひろえむ さんの Web サイト

分類:[C#] 

No5999に返信(tomokoさんの記事)
> 私は今C#でプログラムを作成しているのですが、
> なかなか共通関数をうまく作れません。
> 下記のものを共通でうまくまとめたいと思っております。

あくまで、私がやるならですが・・・・

まず、TestInfoクラスをこのように変えました。

public class TestInfo
{
private string mstrCode1 = string.Empty;
private string mstrCode2 = string.Empty;

public const int Code1Length = 3;
public const int Code2Length = 4;
public const int CodeLength = Code1Length + Code2Length;

public string Code1
{
get { return _code1; }
}

public string Code2
{
get { return _code2; }
}

public TestInfo(string strTarget)
{
if(strTarget < CodeLength) {
throw new ArgumentOutOfRangeException("Lengthは7以上ないと・・・");
}
mstrCode1 = strTarget.Substring(0, Code1Length);
mstrCode2 = strTarget.Substring(Code1Length, Code2Length)
}
}

コンストラクタで文字列を切り離すようにしています。

次にTestクラスですが、冗長に感じたのでStreamからStringを取得するメソッドを切り離してみました。

class Test
{
//Streamから読み出し
public string GetTestFile(string astrFilePath)
{
string strAllData = string.Empty;
using(StreamReader sr = new StreamReader(astrFilePath) {
strAllData = sr.ReadToEnd();
sr.Close();
}
return strAllData;
}

//取り込み処理?
public void TestFileTorikomi(string astrFilePath)
{
string astrAllData = GetTestFile(astrFilePath);
for (int intIndex = 0; intIndex < astrAllData; intIndex += TestInfo.CodeLength)
{
string strTarget = astrAllData.Substring(intIndex, TestInfo.CodeLength);
TestInfo ti = new TestInfo(strTarget);
}
}
}

こんな感じかなぁ・・・ まま、ちょっとそのままコーディングしたので、テストしておりませんが・・・(^^;;;

参考になるかわかりませんが、あくまで私ならばということで(^^;;;

0
引用返信 編集キー/
■6012 / inTopicNo.3)  Re[2]: 共通関数にする為のロジック?
□投稿者/ ひろえむ 二等兵(3回)-(2006/08/26(Sat) 08:31:14)
ひろえむ さんの Web サイト

分類:[C#] 

2006/08/26(Sat) 12:57:53 編集(投稿者)

わわ、見ていてBug発見(^^;;;

TestInfoクラス
まず、
> public string Code1
> {
> get { return _code1; }
> }
>
> public string Code2
> {
> get { return _code2; }
> }
ここは
> public string Code1
> {
> get { return mstrCode1; }
> }
>
> public string Code2
> {
> get { return mstrCode2; }
> }
こうで、んでもって・・・

> if(strTarget < CodeLength) {
ここは
> if(strTarget.Length < CodeLength) {
こうですね(^^;;;

あと、TestクラスのTestFileTorikomiメソッドの中にある・・・
> for (int intIndex = 0; intIndex < astrAllData; intIndex += TestInfo.CodeLength)
ここは
> for (int intIndex = 0; intIndex < astrAllData.Length; intIndex += TestInfo.CodeLength)

こうですね(^^;;;

そっか、Tabは表示されないのか・・・(^^;;;

やっぱ、ちゃんとテストしてからあげなきゃだめですね(^^;;;おはずかしい。

0
引用返信 編集キー/
■6056 / inTopicNo.4)  Re[3]: 共通関数にする為のロジック?
□投稿者/ tomoko 二等兵(2回)-(2006/08/27(Sun) 03:31:05)

分類:[C#] 

ありがとうございます。
コンストラクタの箇所で、
>mstrCode1 = strTarget.Substring(0, Code1Length);
>mstrCode2 = strTarget.Substring(Code1Length, Code2Length)
で、コードをセットしておけば、
TestInfo ti = new TestInfo(strTarget);
でTestInfoを返せると言う訳ですね♪
凄く参考になりました。
確かに良いと言えばいいのですが、
こうなるとTestInfo2が必要になった時に、フィールドがCode1,2,3の場合は、
コンストラクタに、
mstrCode1 = strTarget.Substring(0, Code1Length);
mstrCode2 = strTarget.Substring(Code1Length, Code2Length)
mstrCode3 = strTarget.Substring(Code2Length, Code3Length)
というような感じで作らないといけないという事になるのですね。
そして、TestInfo3が必要になった時に、
フィールドが、Code1,2...10が必要になった時は・・・と思うと、
コンストラクタの箇所にロジックを書かずに、
共通で書いて、呼ぶだけがいいなーというのが希望です。
TestInfo ti = new commonInfo(strTarget);//←例えばこんな感じ
共通で作るのは不可能なのかな?
教えてもらっているのに、文句言ってしまってスミマセン。
(本当にスミマセン m(__)m)
何かアドバイスがあればよろしくお願いします。
(いろいろとロジックを覚えたいので・・・)
今は、ひろえむさんのやり方でいこうと思います。
ひろえむさんありがとうございました。

0
引用返信 編集キー/
■6057 / inTopicNo.5)  Re[4]: 共通関数にする為のロジック?
□投稿者/ ひろえむ 二等兵(5回)-(2006/08/27(Sun) 06:57:25)
ひろえむ さんの Web サイト

分類:[C#] 

2006/08/27(Sun) 07:06:43 編集(投稿者)

No6056に返信(tomokoさんの記事)
> 確かに良いと言えばいいのですが、
> こうなるとTestInfo2が必要になった時に、フィールドがCode1,2,3の場合は、
> コンストラクタに、
> mstrCode1 = strTarget.Substring(0, Code1Length);
> mstrCode2 = strTarget.Substring(Code1Length, Code2Length)
> mstrCode3 = strTarget.Substring(Code2Length, Code3Length)
> というような感じで作らないといけないという事になるのですね。

んー、Codeの数が可変であるならば、その最小単位のクラスを作ってそれをListなどのコレクションクラスで持つのがいいのかもしれませんね。 もしくは、それらをまとめるクラスを1つ作るとか。 

そうなるとクラスの命名ももう少し考えたほうがいいかも・・・。

まぁ、いずれにしてもこの処理以降に行う処理の内容にもよるので、これ以上の助言はあえて避けておきますが、変更の発生しやすい場所、変更の発生しにくい場所を考えてクラスを構成するといいかと思いますよ。

ちなみに・・・
>mstrCode3 = strTarget.Substring(Code2Length, Code3Length)

>mstrCode3 = strTarget.Substring(Code1Length+Code2Length, Code3Length)
かな。

まぁ、こういう演算もこれらをまとめるクラスのコンストラクタでやると楽かもしれませんね。

0
引用返信 編集キー/
■6121 / inTopicNo.6)  Re[5]: 共通関数にする為のロジック?
□投稿者/ tomoko 二等兵(3回)-(2006/08/29(Tue) 22:24:48)

分類:[C#] 

私の力では共通のクラスは作れなかったので、共通クラスは断念しました。
結局、コンストラクタでやるのは、ファイル処理専用になってしまい、
使いまわしがきかなくなるので、〜infoクラスには処理を追加するのも止めて、
ひろえむさんの良い箇所だけとって、privateのメソッドを使う事になりました。
お世話になりました。
また何かアドバイスがありましたら、引き続きよろしくお願いします。

0
引用返信 編集キー/
■6127 / inTopicNo.7)  Re[6]: 共通関数にする為のロジック?
□投稿者/ ひろえむ 二等兵(6回)-(2006/08/29(Tue) 23:41:33)

分類:[C#] 

No6121に返信(tomokoさんの記事)
> 私の力では共通のクラスは作れなかったので、共通クラスは断念しました。
> 結局、コンストラクタでやるのは、ファイル処理専用になってしまい、
> 使いまわしがきかなくなるので、〜infoクラスには処理を追加するのも止めて、
> ひろえむさんの良い箇所だけとって、privateのメソッドを使う事になりました。
> お世話になりました。
> また何かアドバイスがありましたら、引き続きよろしくお願いします。

んー、目的が漠然としていてアドバイスが難しいところですが、テキストを分割するだけでいいのであれば、配列にしてもいいんじゃないかなぁという気もします。

たとえば、

private List<string> DivText(string astrData, int[] aintLengthArray) {
List<string> lstData = new List<string>();
int intStartPos = 0;
for(int intIndex = 0; intIndex < aintLengthArray.GetLength(0) ; intIndex++) {
string strTarget = astrData.Substring(intStartPos, aintLengthArray[intIndex]);
lstData.Add(strTarget);
intStartPos += aintLengthArray[intIndex];
}
return lstData;
}

なんてな感じでメソッド作って
int[] intTargetDataLength = { 3, 4, 5 };
      List<string> lstData = DivText("111222233333", intTargetDataLength )
とかかっておくとか。

項目がわかりにくいならenumで定義しておくとか工夫すれば・・・。

まぁ、前回も言いましたが以降の処理の内容にもよるので、これがtomokoさんが行おうとしている要件に合うかどうかわかりません。

情報が少なすぎて、前回はあえて書きませんでしたが、もう少し詳細がわからないとアドバイスできないので、何を困っていて、どう共通にしようとしているのかもう少し明確にしていただきたかったところです。

たとえば、テキストファイルの種類がいろいろあって、それらを処理するために複数のレイアウトの書式を管理したいとか・・・。

まぁ、解決したのであればいいのですが・・・。


0
引用返信 編集キー/
■6131 / inTopicNo.8)  Re[7]: 共通関数にする為のロジック?
□投稿者/ tomoko 二等兵(4回)-(2006/08/30(Wed) 01:58:15)

分類:[C#] 

夜遅くアドバイスありがとうございます。
処理のやりたい事というのが、あくまでも、ファイルのデータを一番始めのTestInfoクラスに入れたいという事なのです。
なぜかというと、TestInfoクラスはその後でいろいろな処理メソッドに入れて使うからなのです。
本当にメソッドに渡したらいいだけもメソッドがたくさんあるのです♪
なので、TestInfoに綺麗に値を入れる関数が出来たら言い訳なのです。
ただ単にファイルのデータを切るという関数は必要ないという事なのです。
ファイルのデータを切って、どうやってTestInfoに値を与えるか?が問題なのです。
あんまりTestInfoのコンストラクタを変えるとかは、駄目なのです。
他にも、データベースから値をTestInfoに与えたりとか、色々使われるので、
処理がごっそりと変わるのは駄目なのです。
自動で値をset出来たら嬉しいなー♪って思っています。
パラメータを上手く与えたりしてとか・・・
リフレクションとかも使えないかな?って思って勉強したのですが、自分では不可能です。
ファイルのデータは本当に文字の羅列です。
【abcdefg123456fdskjlsdjffsdjlfjsdjf】←こんな感じです。改行もありません
このような感じでどうでしょうか?
ちなみに、この問題は解決したというよりか、あきらめたって感じです・・・
(正直無理なのかなーという感じがしているので・・・)
それではおやすみなさい。

0
引用返信 編集キー/
■6132 / inTopicNo.9)  Re[8]: 共通関数にする為のロジック?
□投稿者/ ひろえむ 二等兵(7回)-(2006/08/30(Wed) 05:50:41)

分類:[C#] 

No6131に返信(tomokoさんの記事)
> 処理のやりたい事というのが、あくまでも、ファイルのデータを一番始めのTestInfoクラスに入れたいという事なのです。

んー、何が手間で共通関数にしようと思ったのかが明確ではないので、もし、そのレイアウト変更が手間だというのであれば、自動でレイアウトを定義するメソッドを作ればいいし、そうでないのであれば、そのまま素直にクラスを作る方がいいように思いますが・・・。

あまり、複雑にしても余計にわからなくなるので単純に作るほうがいいと思いますよ。



0
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -