C#のジェネリッククラスを使って座標クラスを作成する方法

このQ&Aのポイント
  • C#で座標クラス(XY座標を計算するクラス)を作成する際に、ジェネリッククラスを使用する方法を探しています。
  • ジェネリッククラスを使用することで、座標クラスに用いるデータの型を汎用的に設定することができます。
  • しかし、ジェネリッククラスを使用する場合、基本的な演算子の使用が制限されるため、演算を可能にする方法を模索中です。また、値の型に制限を加える方法も知りたいです。
回答を見る
  • ベストアンサー

C#のジェネリッククラス

 現在C#で座標クラス(XY座標を計算するクラス)を作ろうとしています. 座標クラスに用いるデータは二つの数字になる訳ですが,データの型に汎用性を持たせたいです.以前C++で作る場合は,テンプレートクラスを用いてすんなりとOKだったのですが,C#では勝手が違うようで少し困っています. //座標クラス class vertex<T>{ private T x, y; ~ } のような感じでクラスを作っていきたいのですが,このままだとC#の場合「x + y」や「x < y」のような基本的な演算子が使えなくなってしまいます.もちろん演算子を使わなくても同じような事が出来たらいいのですが...  一応自分で調べた結果,TにIComparableを実装の制限を加えれば比較は出来る事が分かりました.しかし,加算や減算を行うようにするのはどうすればいいのかまだ良く分かっていません.  x.Add(y)の様な形でも良いので,演算を可能にするようなジェネリクスクラス(メソッド)の作り方は無いでしょうか?もちろん演算子が使えるならなお嬉しいです(今まで調べた結果では難しそうに感じてますが...><).  また,Tの型を値のみに制限する方法は無いでしょうか?doubleやintやlongのみに制限したいのです.「where T : struct」はなんとなく意味が違うような...?あまりそこの所はまだよく理解はしていません.Javaだと「Numberクラスを継承しているクラス」とすれば簡単に制限できたのですが...C#はまだ初心者であまりよく理解できていないのが現状です>< よろしくお願いします. 一応参考までに... 【O S】Mac OS 10.7(最終的にはWindowsに実装予定) 【プログラミング歴】7年(C++ 3年, Java 4年, C# 6ヶ月)

質問者が選んだベストアンサー

  • ベストアンサー
  • Egtra
  • ベストアンサー率100% (1/1)
回答No.2

C#のジェネリックで演算子が使用できないのは有名な決まりです。 残念ながら、直接的な解決方法はほとんどありません。 このページにいくつか案が挙げられているので、参考になると思います。 http://ufcpp.net/study/csharp/sm_genericop.html ちなみに、上のページには「1. C# 4.0 で導入される dynamic キーワードを使う」について詳しく書かれていないので、簡単に例を書いておきます。 class Vector<T> { T x, y; Vector(T x, T y) {} static Vector<T> Add(Vector<T> v1, Vector<T> v2) { dynamic x = v1.x; dynamic y = v2.y; return new P<T>(x + v2.x, y + v2.y); } static Vector<T> operator+(Vector<T> v1, Vector<T> v2) { return Add(v1, v2); } }

参考URL:
http://ufcpp.net/study/csharp/sm_genericop.html
hira_kazu
質問者

お礼

 例まで挙げていただき,回答ありがとうございます^^  URLも参考にして,もう一度違う方向で試行錯誤してみます

その他の回答 (1)

  • hogya
  • ベストアンサー率67% (49/73)
回答No.1

独自のデータ型を定義した後に演算子のオーバーロードを定義すればご希望にそうような形にできそうな気がします。 この場所で全て説明するのも難しいので、まずは下記のようなまとめサイトをご覧になって試されてはいかがでしょう。詳細な部分はC#はクラスライブラリリファレンスが充実していますので、そちらを参照すればよいかと思います。 プログラミング歴がお長いのでそれほど難しくはないと思います。 http://ufcpp.net/study/csharp/oo_operator.html また、ジェネリック型の型の制限については、ジェネリック型パラメータの制約を使うことによって、型パラメータを特定の基本クラスを持つ型、既定のコンストラクタを持つ型、参照型または値型である型に制約することができます。

hira_kazu
質問者

お礼

 回答ありがとうございます.  一度試してみます^^

関連するQ&A

  • コレクションクラスの選択

    VC++6.0 + MFCを利用しています。 下のような、複数の点とその座標を記録しておいて利用するためどのような実装にすればいいのか悩んでいます。 主な利用方法は、「点番号Xから座標をgetする」で、たまに、「すべての点の中でx座標が一番小さいほうから10番目の中にあり、かつ、y座標が最も小さな点番号をgetする」というような並び替えが必要となる利用が予想されます。 最初の使い方だけだったら、CMapクラスで、点番号をキー、各座標の構造体を値にすれば、実装できますが、それだと2番目の使い方のとき、毎回全データを見ないといけなくなって非常に効率が悪い気がします。 どのようなデータ構造にすれば効率よくこのような実装ができるでしょうか。できれば既存のクラスを組み合わせて使いたいのですが、詳しい方教えていただけますか。 点番号 x座標 y座標 z座標    1   1.0   1.1   1.2    2   2.0   2.3   4.5         :         :

  • ゲームプログラミング クラス構造について

    現在、ソフトウェアエンジニアめざしてプログラミング勉強中の者です。 とりあえず、"The C Programing Language"(Kernighan&Ritchie) をようやく読み終え、最近C++の勉強を始めました。 そこで! 楽しくオブジェクト指向を身につけようと、簡単なゲームプログムを作りながら勉強する事にしたのですが、例えばマリオのような横スクロールアクションゲームの場合、どのようにオブジェクトを分類したら良いのでしょう? たとえば、どのような基底クラスを作り、そこからどのような派生クラスを作ったら良いのでしょうか? かんたんな構成の用な物を作っていただけるとうれしいです。 (例) キャラクター(X,Y座標が常に変化し動きまわる)  主役(ボタン操作によってX,Y座標が変化)   敵(プレイヤーのボタン操作とは関係なく動き回る) Action  重力(キャラクターX,Y座標にy方向加速度をくわえる)  MAP  床(重力によりキャラクターが下へ行き過ぎないようよう、Y座標の移動制限を制限)   ブロック 例は適当に作った物ですが、こんな感じにキャラクターのX,Y座標は重力などに対してPrivate:にするべきなのか?などもかいてあるとうれしいです^^

  • C#にて別クラスの関数を使いたい

    C#にて、別クラスの関数を使用する方法を教えてほしいです。 下記のような、構造体を受け取るメソッドを作りました。 ***************************** private struct MyPoint { public int x; public int y; } private void proc1(MyPoint pt) { MessageBox.Show("座標:" ; pt.x + "," + pt.y + "実行結果"); } private void button1_Click(object sender ,System.EventArgs e) { MyPoint pt; pt.x = 10; pt.y = 20; proc(pt); } ***************************** 別のフォームのクラスから、proc1を呼び出したいのですが、やり方がわかりません。 どうか、教えてください。

  • C++で継承元のクラスの代入演算子を呼び出す方法

    C++であるクラス継承したクラスの代入演算子で 継承元のクラスの代入演算子を呼び出す方法がわかりません。 こんな感じのソースです。 class T { T& operator=(const T &t) { } } class U :: T{ U& operator=(const U &u) { // ここでT.operator=()の代入演算を実行したい } } ((T)(*this)).operator=((T)(u))のようにキャストすればいけるかと思ったんですが、 コンパイルエラーでした。 よろしくお願いします。 また、これはプログラム上好ましくない手法でしたら、 別な実現方法をお教えください。

  • 派生クラスから基本クラスprotectedメンバへのアクセスについて

    C++初心者です。 以下のような基本クラスcoordと、その派生クラスquadがあり、quadクラスに関して=演算子をオーバーロードしました。 class coord { protected: int x, y; }; class quad : public coord { public: quad operator=(coord &ob2); }; quad quad::operator=(coord &ob2) { x = ob2.x; y = ob2.y; } するとob2からxにアクセスできないとエラーが出ます。 quadクラスのメンバ関数内なので、基本クラスのprotectedメンバにはアクセスできると思ったのですが、違うのでしょうか。 ご教授お願いします。

  • C言語のプログラムに関することで質問です。

    C言語のライブラリを利用したプログラムのことで質問なのですが、座標xとyの成分から、ベクトルの角度(t)と大きさ(r)を求めるプログラムを作りました。しかし、このままのプログラムだと、ある場合のときに限り、正しい値が返されなくなるらしいのですが、それはどのような場合で正しい値が返されなくなってしまうのかを教えてください。また、正しい値がでるようにするにはどこをどう直したらよいのでしょうか? 自分でも考えてみたのですが、分からず困っています。分かる方どうかよろしくお願いいたします。 #include <stdio.h> #include <stdlib.h> #include <math.h> #define square(x) ((x) * (x)) //ベクトルの角度θを返す関数 double theta(double x, double y) { return atan(y / x); } //ベクトルの大きさを返す関数 double radius(double x, double y) { return sqrt(square(x) + square(y)); } int main(int argc, char **argv) { double x, y; //x, yは座標 double t, r; //t, rは極座標 if(argc == 3 && (x = atof(argv[1])) && (y = atof(argv[2]))) { t = theta(x, y);  //極座標tを計算 r = radius(x, y); //極座標rを計算   //ベクトルの角度と大きさを表示 printf("t = %f, r = %f\n", t, r); } return 0; }

  • 数学Cの2次曲線の問題がわかりません

    数学Cの2次曲線の問題がわかりません 円x^2+y^2=1のy>0の部分をCとする。C上の点Pと点R(-1,0)を結ぶ直線PRとy軸の交点をQとし、その座標を(0,t)とする。 (1)点Pの座標を(cosθ,sinθ)とする。cosθとsinθをtを用いて表せ。 (2)3点A,B,Sの座標をA(-3,0),B(3,0),S(0,1/t)とし、2直線AQとBSの交点をTとする。 点PがC上を動くとき、点Tの描く図形を求めよ。 (1)からわかりません。 お願いします!

  • C++について教えてください。(初心者です)

    現在C++についての学習を進めているのですが、 2項演算子のオーバーロードで理解できないところがありますので、よろしかったらご教授ください。 //+をcoordクラスに対してオーバーロードする #include<iostream> using namespace std; class coord{ int x,y; public: coord() {x=0;y=0;} coord(int i,int j) {x=i;y=j;} void get_xy(int &i,int &j) {i=x;j=y;} coord operator+(coord ob2); }; //+をcoordクラスに対してオーバーロードする coord coord::operator+(coord ob2) { coord temp; temp.x = x + ob2.x; temp.y = y + ob2.y; return temp; } int main() { coord o1(10,10),o2(5,3),o3; int x,y; o3 = o1 + o2; o3.get_xy(x,y); cout << "(o1+o2) X:" << x << ",Y:" << y << endl; return 0; } この文の中で、o3.get_xy(x,y);というコードがありますが、 ここの部分がよくわからないのです。 そもそも、引数としてx,yがありますが、これはprivateメンバを 見に行きなさい。っと言っているのでしょうか? main()の中から直接使っている?? それとも?? すいません。この辺の理解が薄いようなので、2項演算子のオーバーロードとは関係ないかもしれませんが、教えてください。 よろしくお願いします。

  • 陰関数の連立方程式

    陰関数の連立方程式 プログラミング言語で数値解析のアルゴリズムを実装しているのですが、 媒介変数表示された陰関数の連立方程式の解法で苦しんでいます。  x = fx(t)  y = fy(t)  x = gx(t)  y = gy(t) の一般的な解法を教えてください。 具体的には、  サイクロイド曲線と放物線の交点座標   x(t) = A(t-sin(t))   y(t) = A(1-cos(t))   y(x) = Bx^2  インボリュート曲線とベジエ曲線の交点座標   x(t) = C(cos(t)+tsin(t))   y(t) = C(sin(t)-tcos(t))   x(t) = (t-1)^3x1 + 3(t-1)^2tx2 + 3(t-1)t^2x3 + t^3x4   y(t) = (t-1)^3y1 + 3(t-1)^2ty2 + 3(t-1)t^2y3 + t^3y4 等の解 t を数値解析によって求めたいということです。 任意の陽関数の連立方程式  y = f(x)  y = g(x) を満たす x を求めるアルゴリズム、要するに  f(x) - g(x) = 0 の解を求めるアルゴリズムは、既に実装済みです。 ですので、ここまで持ち込んでいただければ必要十分です。 簡単に陽関数の解法のアルゴリズムに持ち込めるかと思ったのですが...

  • a(x+b)²+cの式に置き換えて頂点などを求める

    英文混じりですみません。 問題例→ f(x)=2x²-12x+13 Express f(x) in the form a(x+b)²+c 答え例→ f(x)=2x²-12x+13→ 2(x²-6x+ )+13→ 2(x²-6x+ 9 )+13 -18→ 2(x-3 )²-5 同じ種類の質問でsymmetry(対称軸 ) 及びvertex(頂点)を求めよという次の問題がよくわかりません。 1)y= -2x²-4x-5 答えsymmetry= -1, vertex=(-1, 3) 2)y= 3x-2x²-2 答えsymmetry= 0.5, vertex=(0.5, -1.25) 例えば1)ですが私の答えはsymmetry= -1, vertex=(-1, -3)となり頂点のyが合いません。答えが間違っていますか? 又2)の問題をa(x+b)²+cの式に置き換えるのはどうしたらいいですか? -(2x²-3x)-2までやってみるのですが(2x²-3x)を(x+b)²の形にするのがわかりません。 又答えを出す為にsymmetry(対称軸 )を求める-b/2aというのを使ってもsymmetry(対称軸 )は3/4=0.75で答えと一致しないのです。