- PR -

引数であるobject型を復元する方法(C#)

投稿者投稿内容
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-03-22 08:12
引用:

ひろしさんの書き込み (2004-03-20 01:15) より:

<不満に思う点>
ロジックが正常に機能するかどうかは、AddMain()のGetType().nameの判定が
正しいことを前提にしています。これではバグが入り込む危険性があります。
ただし、引数の柔軟性は確保したいのでobjectによる引渡しを放棄して
メソッドをoverrideする手法は採用したくありません。


 どういうときに、「判定が正しくない」結果になるのでしょう?
 MSDN Magazineだったと思いますが、C#では1度作ったクラスは永久に(この「永久」がどういう意味かは図りかねる)そのクラスである、のだそうです。したがって、「正しくない」結果というのは、どのような場合を想定されているのでしょう?

 また、クラス/型の判定は、どこかのスレッドで書いていますが、
if (typeof 変数 is gettype(クラス))
で調べます。お望みなら、クラスのバージョンチェックができる方法もあります(シリアライズする)。

〜〜〜
ん〜、VB.NETとC#で違うようです。
VB.NET:
  If TypeOf 変数 Is GetType(クラス) 〜
C#:
  if (変数 as クラス) 〜

[ メッセージ編集済み 編集者: Jitta 編集日時 2004-03-22 08:19 ]
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2004-03-22 14:54
引用:

Jittaさんの書き込み (2004-03-22 08:12) より:
ん〜、VB.NETとC#で違うようです。
VB.NET:
  If TypeOf 変数 Is GetType(クラス) 〜
C#:
  if (変数 as クラス) 〜
[ メッセージ編集済み 編集者: Jitta 編集日時 2004-03-22 08:19 ]



VB.NETでの型判定は、
  If TypeOf 変数 Is 型 Then

のはずです(サブクラスも含まれます)。
GetType演算子は指定しません(できません)。
型の部分はクラスでも構造体でもOKです。

C#の方は普段、全然使っていないので、へぇーそんな判定方法があるんだと思って、
念のためWebでas演算子について調べてみました。
as演算子は安全なキャストのための演算子ですよね?だとすると

if (変数 as クラス != null) {
// 変数がその型
}

ではないでしょうか?
また、この方法の場合はasの後ろはクラスでないと怒られるようです。(例えばintだとNG)

以下は単なる推測ですが、この方法は実際にキャストを行った結果、
異なる型の場合にnullを返すという仕様の副次的な利用方法になるので、
単純に型チェックをする方法としてはあまり適切ではない気がするのですが、
その辺どうなんでしょう?(それとも割と普通に使われるのでしょうか?)>C#使いの方
アティ
ベテラン
会議室デビュー日: 2003/08/14
投稿数: 91
お住まい・勤務地: KANAGAWA
投稿日時: 2004-03-22 15:16
引用:

Jittaさんの書き込み (2004-03-22 08:12) より:

(省略)

ん〜、VB.NETとC#で違うようです。
VB.NET:
  If TypeOf 変数 Is GetType(クラス) 〜
C#:
  if (変数 as クラス) 〜


C#でもisで判定しますよ。

コード:
  if (変数 is クラス) 〜

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-03-22 16:45
  式(null)は、「偽」となるのでは?
char *a = null;
操作
if (a) {
 sprintf("%s\n", a)
}
・・・なんてことをやっていたのだが(ただし、C/C++)?


 VB.NETは受け付けてくれなかったな。C#もダメ?
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2004-03-22 17:36
引用:

Jittaさんの書き込み (2004-03-22 16:45) より:
  式(null)は、「偽」となるのでは?



C#はJava同様、条件式はTrue/Falseを返す式でないといけないようです。

error CS0029: 型 'asの後ろで指定したクラス' を型 'bool'に暗黙的に変換できません。

となります。
なので、as演算子を使うのであれば、私が補足した下記のような判定式になります。

> if ((変数 as クラス) != null) {

(わかりやすさのため()を増やしました。)
開発環境ないので、エディタで書いてcscでコンパイルし動作確認済みです。


引用:

アティさんの書き込み (2004-03-22 15:16) より:
コード:
 if (変数 is クラス) 〜





フォローありがとうございます。is演算子でよかったんですね。
ちゃちゃっと実験コードを書いて動作確認できました。
いのつち
ベテラン
会議室デビュー日: 2002/05/14
投稿数: 73
投稿日時: 2004-03-22 17:49
引用:

if (変数 as クラス != null) {
// 変数がその型
}


以下は単なる推測ですが、この方法は実際にキャストを行った結果、
異なる型の場合にnullを返すという仕様の副次的な利用方法になるので、
単純に型チェックをする方法としてはあまり適切ではない気がするのですが、
その辺どうなんでしょう?(それとも割と普通に使われるのでしょうか?)>C#使いの方


// 例1
ClassA a = obj as ClassA;
if( a != null)
{
a.Method1();
}
// 例2
if( obj is ClassA)
{
ClassA a = (ClassA) obj;
a.Method1();
}

C#では、キャストするときに型チェックが行われるので、例2の場合
2重で型チェックをしていることになるそうです。

従って型チェック後にその型を使う場合は、例1のように、as を使う方が
よいそうです。型チェックとNULLチェックでは、NULLチェックのほうがコストが低い
んでしょうね。
Jeffrey Richterの受け売りで、自身で疑って確認したわけではないのですが・・。

私はas を使うことが多いです。


アティ
ベテラン
会議室デビュー日: 2003/08/14
投稿数: 91
お住まい・勤務地: KANAGAWA
投稿日時: 2004-03-22 17:51
引用:

Jittaさんの書き込み (2004-03-22 16:45) より:
  式(null)は、「偽」となるのでは?
char *a = null;
操作
if (a) {
 sprintf("%sn", a)
}
・・・なんてことをやっていたのだが(ただし、C/C++)?


 VB.NETは受け付けてくれなかったな。C#もダメ?



C#だとif文の条件には、

暗黙的に bool に変換できる式、または true 演算子および false 演算子のオーバーロードを含む型。(.NET Framework クラス ライブラリより)

でないといけないです。あと、System.Booleanは構造体なので、nullは代入できないです。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-03-23 09:20
>アティさん、よねKENさん

 ありがとうございます。VB.NETと同じく、C#でも、if文の判定はbooleanでなければならない、と(._.)φ

 Borland Togetherを入れて、VS.NETを修復インストールして、GrapeCityのコンポーネントを入れたり消したり…をしたためか、C#がおかしいのです。C#だけなので、Togetherだろうな。。。それでもMSDNは見られるだろ>自分
#XPのWindowsUpdateも効かないので、OSから再インストール・・・

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