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

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

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

Re[3]: クラスの作り方について教えてください


(過去ログ 116 を表示中)

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

■68456 / inTopicNo.1)  クラスの作り方について教えてください
  
□投稿者/ まおまお (1回)-(2013/10/22(Tue) 09:06:19)

分類:[C#] 

UserControl にペイントボックスを張り付けて、
そこに、サイズが異なる(ただし、縦、横の数は同じ)
の内部配列データを表示させたいのですが

public partial class MyGrid : UserControl
{
object [][] Rows;
}

FlexGrid のように fgrid1[0, 0] でも
データが取得できるようにするにはどうすればよいのでしょうか?


object obj2 = myGrid1.Rows[0, 0]; ←こちらはOK
object obj1 = myGrid1[0, 0]; ←こちらはNG
引用返信 編集キー/
■68459 / inTopicNo.2)  Re[1]: クラスの作り方について教えてください
□投稿者/ 魔界の仮面弁士 (385回)-(2013/10/22(Tue) 09:50:27)
No68456 (まおまお さん) に返信
> public partial class MyGrid : UserControl
> {
> object [][] Rows;
> }
> FlexGrid のように fgrid1[0, 0] でも
> データが取得できるようにするにはどうすればよいのでしょうか?

public partial class MyGrid : UserControl
{
 private object[,] rows;
 public MyGrid()
 {
  rows = new object[3, 10];
 }
 public object this[int x, int y]
 {
  get { return rows[x, y]; }
  set { rows[x, y] = value; }
 }
}


> UserControl にペイントボックスを張り付けて、
ここでいう「ペイントボックス」とは、どのような物を指しているのでしょうか。
(少なくとも .NET の標準クラスに、PaintBox というクラスは無かったはず…)


> そこに、サイズが異なる(ただし、縦、横の数は同じ)
> の内部配列データを表示させたいのですが
「マイ ピクチャ」フォルダのサムネイル表示(縮小表示、大アイコン表示)を連想しました。

縦横数が同じでサイズが異なるなら、Size あるいは SizeF 型の
二次元配列を持ってみては如何でしょうか。

private Size[,] boxes;
引用返信 編集キー/
■68462 / inTopicNo.3)  Re[2]: クラスの作り方について教えてください
□投稿者/ まおまお (2回)-(2013/10/22(Tue) 11:01:12)
早速のお返事どうもありがとうございます。
ペイントボックスはピクチャーボックスの間違いでした。
すみません。

public object this[int x, int y]
でとることができました。
ただ、Rows[][] が取得できないので

このようにしてみました。

public partial class MyGrid : UserControl
{
 public object[][] Rows;

 public MyGrid ()
 {
  InitializeComponent();
 }

 public object this[int x, int y]
 {
  get { return Rows[x][y]; }
  set { Rows[x][y] = value; }
 }

 private void MyGrid_Load(object sender, EventArgs e)
 {
  Rows = new object[][] {
   new object[]{"00", "01", "02"},
   new object[]{"10", "11", "12"}
   };
 }
}

これで myGrid1[0,1], myGrid1.Rows[1][1]
で取得できるようになりました。

次に、管理するためのクラスを追加すると
クラス名と配列名が重複してしまいます。

class Rows
{
  int Count;
}

どうすればよいのでしょうか?

引用返信 編集キー/
■68464 / inTopicNo.4)  Re[3]: クラスの作り方について教えてください
□投稿者/ 魔界の仮面弁士 (386回)-(2013/10/22(Tue) 11:23:48)
No68462 (まおまお さん) に返信
> public object[][] Rows;

フィールドを public で公開するべきではありません。外部から
「myGrid1.Rows = null;」とか「myGrid1.Rows[1] = myGrid2.Rows[3];」
などとして、容易に書き換えられてしまうからです。

一般的には、編集可能なフィールドは private にしておき、それを
public (あるいは protected)な プロパティとして公開するようにします。

> class Rows
RowsCollection クラスを作りたいのであれば、そのクラスに
List<> 型か ReadOnlyCollection<> 型を継承させるのが良いかと。
引用返信 編集キー/
■68465 / inTopicNo.5)  Re[3]: クラスの作り方について教えてください
□投稿者/ Hongliang (105回)-(2013/10/22(Tue) 11:29:14)
> 次に、管理するためのクラスを追加すると
> クラス名と配列名が重複してしまいます。

public partial class MyGrid : UserControl
{
    class Rows
    {
       int Count;
    }
}

ではなく、

public partial class MyGrid : UserControl
{
}
class Rows
{
   int Count;
}

のようにすればいいのでは。
// フィールドとか何とかの"べき論"は置いておく。

引用返信 編集キー/
■68468 / inTopicNo.6)  Re[4]: クラスの作り方について教えてください
□投稿者/ まおまお (4回)-(2013/10/22(Tue) 13:04:41)
いろいろどうもありがとうございます。

今までの整理をすると

MyGridクラスを作成します。
MyGrid myGrid = new MyGrid();
において

1. myGrid[ix, iy] で配列データの読み書きができる
2. myGird.Rows[ix][iy] で配列データの読み書きができる
3. myGrid.Rows.Count,myGrid.Cols.Count が使用できる

これを実現するためにはどうすればよいのでしょうか?

と、いうことで
myGrid.Rows[ix][iy] を読み書きするために
public 宣言をしました。
引用返信 編集キー/
■68469 / inTopicNo.7)  Re[5]: クラスの作り方について教えてください
□投稿者/ 魔界の仮面弁士 (388回)-(2013/10/22(Tue) 13:35:41)
2013/10/22(Tue) 13:42:07 編集(投稿者)

No68468 (まおまお さん) に返信
> 1. myGrid[ix, iy] で配列データの読み書きができる
インデクサを作成しましょう。作り方は No68459 参照。あとは下記。
http://dobon.net/vb/dotnet/beginner/defaultproperty.html


> 2. myGird.Rows[ix][iy] で配列データの読み書きができる
myGird → myGrid はともかくとして、
x と y が逆かと。

myGird.Rows[ix][iy] ではなく、
myGrid.Rows[iy][ix] では無いでしょうか。

myGrid.Rows[0] で 0 行目、
myGrid.Rows[2] で 2 行目、
myGrid.Rows[2][0] で 2 行目の左端、ということで。


それと、
 myGird.Rows[row][col] = newValue;
はありだと思いますが、
 myGird.Rows[row] = newRow;
は危険ではないでしょうか。

値は差し替え可能でも、行は ReadOnly にしておくか、
または行を差し替えさせるにしても、
 myGird.Rows.Add(newRow);
 myGird.Rows.Insert(rowIndex, newRow);
などとすべきだと思います。
その場合は object 配列ではなく、RowsCollection クラスを用意しましょう。

> 3. myGrid.Rows.Count,myGrid.Cols.Count が使用できる
内部データの持ち方次第ですが、コレクションクラスを用意しましょう。

管理変数をジャグ配列にするか二次元配列にするか DataTable にするかは
お好みで使いやすい物をどうぞ。今回はジャグ配列なのでしょうか?

たとえば行なら、

class RowsCollection : List<行クラス> {} を用意しておき、

public MyGrid : UserControl
{
 private RowsCollection rows = new List<列クラス>();
 public RowCollection Rows
 {
  get { return this.rows; }
 }
}

みたいな感じで。Cols も同様。


あるいは、コレクションを動的に作るならこんな感じ。

 // ReadOnlyCollection<object> でも良いけれど。
 public ReadOnlyCollection<行クラス> Rows
 {
  get
  {
   var rows = new List<行クラス>();
   for(var r = 0; r < 内部配列の行数; r++)
   {
    rows.Add(内部管理のジャグ配列[r]);
   }
   return rows.AsReadOnly();
  }
 }
引用返信 編集キー/
■68485 / inTopicNo.8)  Re[1]: クラスの作り方について教えてください
□投稿者/ Jitta (82回)-(2013/10/22(Tue) 20:57:53)
Jitta さんの Web サイト
No68456 (まおまお さん) に返信
 ちょっと気になるのですが、、、

> public partial class MyGrid : UserControl
> {
>   object [][] Rows;
> }
>
> FlexGrid のように fgrid1[0, 0] でも
> データが取得できるようにするにはどうすればよいのでしょうか?

「object[][]」と、「object[,]」は、型が異なるのではないでしょうか。

「object[][]」は“ジャグ配列”
  要素の配列の長さが等しくなる必要が無い。
  たとえば、次のようにできる。
    object[][] obj = new object[3][];
    obj[0] = new object[10];
    obj[1] = new object[5];
    obj[2] = new object[20];

「object[,]」は“二次元配列”
  こちらは、各要素の長さは等しい。

※参考:『C# 言語仕様 Version 4.0』「1.8 配列」

引用返信 編集キー/
■68487 / inTopicNo.9)  Re[2]: クラスの作り方について教えてください
□投稿者/ 魔界の仮面弁士 (390回)-(2013/10/22(Tue) 22:01:07)
2013/10/22(Tue) 22:08:34 編集(投稿者)

No68485 (Jitta さん) に返信
> 「object[][]」と、「object[,]」は、型が異なるのではないでしょうか。

最初の No68456 だけを見ると、確かに混同しているようにも思えますが、
もしかしたら今回は意図的に jagged-array 化されたのかも知れないですね。


「object[] cells = myGrid1.Rows[n];」と書けるようにしようとしたものの、
プロパティ名の実装方法を習得されていなかったので、それに類する機能を
フィールド変数で代用しようとした結果、ジャグ配列にされたのだと勝手に想像。

グリッドの値を表現するなら、確かに二次元配列で良いとも思えますが、
その割に、変数名が「行」を連想させる「object[][] Rows;」になっていますし。


まぁ、管理変数をどのように持つにしても、今後 Columns プロパティを
用意することを考えると、プロパティの実装方法はいずれにせよ
身につけておいた方が良いでしょうね。


実装例については No68469 を参照してみてください。>まおまおさん



No68468 (まおまお さん) に返信

C# でプロパティ定義を作るには、「コード スニペット」を使うと便利かと思います。

C# 2005 では、"prop" と打った後で {Tab}キーを 2 回打つことで、
下記のようなプロパティ定義を簡単に挿入できます。

//------------------------------------
private int myVar;
public int MyProperty
{
  get { return myVar; }
  set { myVar = value; }
}
//------------------------------------


このとき、最低限変更すべき個所(データ型、名前)が着色されており、
{Tab} キーを押すごとに、それらの箇所にジャンプするようになっています。



C# 2008 でも同じ機能がありますが、こちらのバージョンでは、
"prop" のスニペットで挿入される定義が、下記のような
「自動実装プロパティ」による簡易表記に変更されています。

//------------------------------------
public int MyProperty { get; set; }
//------------------------------------



なお C# 2010 以降では、"prop" では 2008 同様の自動実装プロパティですが、
"propfull" にて、2005 同様のプロパティ実装も入力できるようになっています。


また、コードスニペットを自分で定義することもできます。
http://bbs.wankuma.com/index.cgi?mode=one&namber=64120&KLOG=108


# 既にプロパティの作り方をご存知でしたら、今回の投稿は無視してください。(^^;
引用返信 編集キー/
■68556 / inTopicNo.10)  Re[3]: クラスの作り方について教えてください
□投稿者/ まおまお (5回)-(2013/10/28(Mon) 11:33:58)
遅くなりました。

えっと、確かにプロパティのうわべだけはわかっていますが。
ちょっとこったことしたりするとわけわかんなくなります。

もう少し自力で勉強しながら解決に向かっていきたいと思います。
また何かわからなかったら教えてください。

どうもありがとうございました。

とりあえず解決(もっと勉強しろよぉー)ということに・・

解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -