- PR -

どんな型でも受け付けて比較できる方法はありますか?

投稿者投稿内容
がらす
ベテラン
会議室デビュー日: 2005/07/14
投稿数: 99
投稿日時: 2006-08-01 08:31
IDクラスを実装し、その中にintのGUIDと、objectタイプのクライエントIDを作ろうとしています。クライエントIDの型はクライエントが自由に決められるようにしたいということで、object にしています。
ID同士を比較する時、GUIDの比較はintなので問題ないのですが、クライエントIDの比較で困っています。クラスのリファレンスが与えられた時にはリファレンス比較をし、値型が渡された時には値の比較をして一致しているかどうかを決めたいのですが、いい方法が思いつきません。以下に、objectを単純に比較したコードを書いてみました。これではリファレンス比較では問題ないのですが、たとえばintが渡された時など、単純なobject の == では、値が同じでもfalseが返ってきてしまいます。

ジェネリックを使った方が良いのかとも思い始めていますが、違う型で作ったID同士を比較する時に問題が出そう(IDをリストに入れておいて、新しいのが来た時に一致するものがあるか探したりするので)で、まだ上手い方法が見つかっていません。

コード:
public class ID
{
   public int guid;
   public object clientID;

   public static bool operator ==(ID id1, ID id2)
      {
         if (id1.guid == id2.guid && id1.clientID == id2.clientID)
            {
                return true;
            }
            else
            {
                return false;
            }
       }   
}



何か良い方法は無いでしょうか。それとも、要求自体がおかしいのでしょうか。
どうぞよろしくお願いします。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2006-08-01 08:47
「何でも」と言うのは不可能です。特定のクラスを比較させるためには、そのクラスをどのようなルールで比較するのかコーディングする必要があります。従って、未知のクラスを何でも比較する事は、そもそもどうやっても出来ません。

このような場合には、比較を行う仮想メンバ関数を持つ共通の基底クラスから派生させる事で実現します。この場合、共通の基底クラスから派生していないクラス(型)同士を比較する事は出来ません。

あるいはtypeof演算子を用いて型を確認した後、それぞれの型に合わせた比較処理を行う事になるでしょう。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-08-01 09:10
引用:

がらすさんの書き込み (2006-08-01 08:31) より:
以下に、objectを単純に比較したコードを書いてみました。これではリファレンス比較では問題ないのですが、たとえばintが渡された時など、単純なobject の == では、値が同じでもfalseが返ってきてしまいます。


if(o1.Equals(o2))
仕様がよくないので実装もテケトーでいんじゃね?(w
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2006-08-01 12:38
引用:

if(o1.Equals(o2))
仕様がよくないので実装もテケトーでいんじゃね?(w


テケトーどころかベストじゃないですか?
コード:
public class ID
{
   public int guid;
   public object clientID;

   public static bool operator ==(ID id1, ID id2)
   {
		if( id1.guid != id2.guid )
		{
			return false;
		}
		
		if( ( id1.object == null ) && ( id2.object == null ) )
		{
			return true;
		}
		
		if( id1.object != null )
		{
			return id1.object.Equals( id2.object );
		}
		else
		{
			return false;
		}
   }   
}


ただ object が参照型のインスタンスを参照している場合、必ずしもリファレンス比較にはなりません。

ぶさいくろうさんの言う通り仕様がよくありません。
「同値」である事を見たいなら必ず「同値」で比較すべきです。
「同値」をみたり「リファレンス」を見たりは駄目でしょう。

#ID クラスの Equals メソッドもオーバーライドする事をオススメします。
_________________
囚人のジレンマな日々
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-08-01 13:00
引用:

囚人さんの書き込み (2006-08-01 12:38) より:
テケトーどころかベストじゃないですか?


あのままじゃまずいっしょ。ってことね。
その後のフォローありがとさん。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-08-01 22:21
まだわからないようなら、、、、



clientID に、あるデータは float、あるデータは int、あるデータは string、あるデータは DateTime、あるデータは独自の型で入っていたら、どうやって比較するの?
がらす
ベテラン
会議室デビュー日: 2005/07/14
投稿数: 99
投稿日時: 2006-08-02 02:25
皆さん、ご意見有り難うございます。

仕様がダメだということなのですが、こんな風に変えてみるとどうでしょう?
2つのclientIDの比較で
- 2つの型が違う場合は false
- 値型が渡された場合、値を比べて、一致するかどうかで true/false
- 値型でない場合はリファレンス比較

クライエントコードを書く人が出来るだけ自由に使える方法を提供しようとしています。独自にIDを持っているならそれを使っても良いし、呼び出しを行うクラス自体をIDに使ってもいいし…という考え方です。
どうぞよろしくお願いします。
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2006-08-02 04:03
何か違和感があると思ったら、参照型の場合は参照比較で"OK"なのか。値型が問題と。

ほんとにそうならEqualsでほぼ解決だと思いますがね。ダメでしたか?
Equalsをオーバーライドされたクラスが渡されたらダメですが。

そもそも、System.Object クラス自体に機能を追加することはできません。

引用:
クライエントコードを書く人が出来るだけ自由に使える方法を提供しようとしています。

かなり不自由(自由だとしても不便)だと思いますが。
実際にIDクラスを比較するコードは、どんな感じで、一体どう自由なのでしょう。

そもそもこれをどんな局面で使うのだろう。

引用:
仕様がダメだということなのですが、こんな風に変えてみるとどうでしょう?
2つのclientIDの比較で
- 2つの型が違う場合は false
- 値型が渡された場合、値を比べて、一致するかどうかで true/false
- 値型でない場合はリファレンス比較

囚人さんがおっしゃっている『「同値」をみたり「リファレンス」を見たりは駄目でしょう。』が、解決されていませんよ。


自由にしたいならIDクラス自体を継承してもらうとかにすればいいんじゃないですかね。

スキルアップ/キャリアアップ(JOB@IT)