- PR -

C#とVB.NETにおける名前空間の扱いの違い

投稿者投稿内容
sia
常連さん
会議室デビュー日: 2004/05/02
投稿数: 38
投稿日時: 2005-11-16 20:24
Jittaさん
どうもです。

>internal だろうが private だろうが、「アクセスできない」というメッセージが出る以上、「存在していること」はわかっているわけです。「使えない」ことと、「存在していることがわからない」は違います。「存在していることがわかる」以上、名前がかぶることは出来ません。

というふうに、アクセシビリティの問題と名前の解決は別問題なのかなー、とか漠然と考えてたわけですが、
C#の言語仕様
http://www.microsoft.com/japan/msdn/library/ja/csspec/html/vclrfcsharpspec_3_8.asp
を読む限り、シナリオによってはアクセシビリティが名前の解決に影響を与えるみたいです。
#まあ、結局のところ、コンパイラ的には見えるか見えないかの違いになってあらわれるのですが。

[ メッセージ編集済み 編集者: sia 編集日時 2005-11-16 20:28 ]
ハニワ祭り
大ベテラン
会議室デビュー日: 2005/11/15
投稿数: 115
投稿日時: 2005-11-16 22:48
siaさん
サンプルコードありがとうございます。
そうです。その状況で間違いありません。
MSDNの「3.8 名前空間と型の名前」にある『アクセス可能であり』と
いう記述が解釈の分かれるところですね。

Jittaさん
説明不足で申し訳ありません。
VB.NETでも参照設定を追加した際、タスク一覧にエラーがでるとのことですが、
プロジェクトを保存後、一度VS.NETを終了して
再度プロジェクトを開くと、エラーが消えてコンパイル可能になると思います。
これはこれで不審ですが‥

外部アセンブリのinternalなクラスでも存在が確認できる以上、
その名前は使えないという意見もあるようですが、
それならば、名前空間だけでなく同名のクラスも作成できない
ような気がしますが、これは許容されてしまいます。

またVB.NETの Imports は名前空間だけでなくクラスの指定も可能であるのに対して
C#の Using では、名前空間のみ指定が可能であることからも、
Using句でわざわざクラス名と名前空間の競合をチェックする意味がわかりません。
まあこの辺りはC#の厳格な(冗長な?)構文チェックゆえの仕様だとは思いますが。


[ メッセージ編集済み 編集者: ハニワ祭り 編集日時 2005-11-16 23:01 ]
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-11-17 01:01
おお〜、「名前空間名」と「クラス名」が同じだったんですね。失礼しました。

…あれ、VS2003 は無理だけど、2005 ならいけるみたいですね…。
using 部分では名前空間しか指定できないのに、クラスや構造体を見るのは確かに変な気が…。

#追記
クラスの方を public にすると、名前衝突で 2005 でもアウト。
しかし、internal にすると 2005 は OK みたいです。
_________________
囚人のジレンマな日々http://blogs.wankuma.com/shuujin

[ メッセージ編集済み 編集者: 囚人 編集日時 2005-11-17 01:03 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-11-17 18:54
引用:

siaさんの書き込み(2005-11-16 20:24)より:

というふうに、アクセシビリティの問題と名前の解決は別問題なのかなー、とか漠然と考えてたわけですが、
C#の言語仕様
を読む限り、シナリオによってはアクセシビリティが名前の解決に影響を与えるみたいです。


引用:

囚人さんの書き込み(2005-11-17 01:01)より:

using 部分では名前空間しか指定できないのに、クラスや構造体を見るのは確かに変な気が…。


ん?あれ?あれ?


 経過としては、

独自の名前空間を作った(仮に Engine とする)
CrystalReport を参照追加した
using Engine とすると、エラーが発生
CrystalReport が、グローバルな前空間に internal な Engine クラスを定義していることがわかった

ってことで良いですか?>ハニワ祭りさん
で、何というエラーが、どこの行で発生するのでしょう?「エラーが発生する」のであれば、それが一番重要な情報です。
『混乱の元なので、エラーメッセージは端折ったり解釈したりせず、出ているまま正確に転写してくださいね。』

 2005-11-16 22:48 によると、using ディレクティブの行で、エラーになっているのかな?で、そのエラーの元が、internal で、アクセスできない、構造体の名前である、と。using ディレクティブは名前空間を指定するんだから、構造体の名前とかぶっていてもいいやん、と?
 これは、ひとつは siaさん の参照先で、「namespace-or-type-name」となっているのが原因でしょうね。名前空間の名前と、クラスや構造体の名前は同列に並べられているようです。つまり、クラスの中にクラスを定義した場合ですね。
 で、MSDN の「C# 言語の仕様 9.3 using ディレクティブ」を参照すると、名前空間の名前だけでなく、クラス名を書くことも許されていることがわかります。名前空間とクラスは、同列ですから、当然ですね。

 ということは、アクセシビリティのチェックがされていない、という問題になるのかな?

 KB を「アクセシビリティ」と「accessibility」をキーに検索してみましたが、これかな?→[FIX] ローダーが Type によって実装されたインターフェイスのアクセシビリティを確認しない
せっかく直したものを後のバージョンで復活させたり、指摘者の意図とは違う形で「修正」されたりすることが、時々あるからorz
___________________________________________________________________
□ written by Jitta on 2005/11/17
□ Microsoft MVP for Visual Developer ASP/ASP.NET Oct.2005-Sept.2006

_________________
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-11-17 19:19
引用:

 で、MSDN の「C# 言語の仕様 9.3 using ディレクティブ」を参照すると、名前空間の名前だけでなく、クラス名を書くことも許されていることがわかります。名前空間とクラスは、同列ですから、当然ですね。


あれ?と思って試したところ、
「using namespace ディレクティブは名前空間に対してのみ使用できます。hogehoge は名前空間ではなくクラスです。」
と出ました。
もしやと思い、

using a = namae.hogehoge;

とすると、何とクラス名が using ディレクティブに書けました。(コンパイラのエラーメッセージ分かりにくいような・・・)

で、
using hogehoge;
形式の場合は名前空間限定で、
using a = namae.hogehoge;
形式の場合はクラスも書ける、という事なんでしょうか。

ならば、
using hogehoge;
と書いているのに、何故わざわざクラスを見に行くのか・・・。「今、名前空間しか駄目って言ったやん!コンパイラさん」

まとめると、
using hogehoge;
としたら
hogehoge が public のとき「using は名前空間しか書けません」
hogehoge が internal のとき 「アクセスできません」

ん〜・・・
_________________
囚人のジレンマな日々
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-11-17 20:05
引用:

囚人さんの書き込み (2005-11-17 19:19) より:


言語仕様を完全に実装しているわけではない、ということでどうでしょう?
2005ではどうでした?
ハニワ祭り
大ベテラン
会議室デビュー日: 2005/11/15
投稿数: 115
投稿日時: 2005-11-17 22:29
確かに、Jittaさんの言うように
『[FIX] ローダーが Type によって実装されたインターフェイスのアクセシビリティを確認しない』
は怪しいですね。

ちなみにCrystalReport(CrystalDecisions.CrystalReports.Engine )が
グローバル前空間に定義しているinternalな構造体名は、
アルファベット全てです。大文字も小文字も‥

まあ、1文字の名前空間を使用することの是非もあるかとはおもいますが、
名前空間同士の衝突しか意識していなかったので‥
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-11-17 23:23
引用:

言語仕様を完全に実装しているわけではない、ということでどうでしょう?
2005ではどうでした?


2005 でもほぼ同様です。
つまり、

using hogehoge;
としたら、
hogehoge が public のとき「using は名前空間しか書けません」
hogehoge が internal のとき 「アクセスできません」

です。
しかし、
アセンブリ1 に (グローバル名前空間)internal hogehoge クラス
アセンブリ2 に hogehoge 名前空間
両方を参照したアセンブリが
using hogehoge
とすると、しっかり internal hogehoge は無視して、hogehoge 名前空間を参照するようです。(2003 では不可)

アセンブリ1 を public hogehoge クラスにすると、
「アセンブリ2 にある名前空間 'hogehoge' が、アセンブリ1 にある型 'hogehoge' と競合しています。」
です。(2003 とはメッセージが違う。2003 は「名前空間しか書けません」)

_________________
囚人のジレンマな日々http://blogs.wankuma.com/shuujin


[ メッセージ編集済み 編集者: 囚人 編集日時 2005-11-17 23:28 ]

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