- PR -

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

投稿者投稿内容
ハニワ祭り
大ベテラン
会議室デビュー日: 2005/11/15
投稿数: 115
投稿日時: 2005-11-15 22:05
いつもお世話になっております。
C#.NET(VS2003)で開発をしております。

C#でプログラムを作っていて困っていることがあるので
質問させてください。

[問題]
現在自分の作成しているC#のプログラムの名前空間と、
参照設定しているサードパーティーのアセンブリの
名前空間ルートにある構造体が衝突してコンパイルできない
という現象が発生しております。
ちなみに衝突しているのはinternalな構造体です。
同様のことをVBで行うと問題なく動いてしまいます。

[再現方法]
@デフォルトの名前空間がないプロジェクトを作成し、
 internalな構造体をクラス外に定義しビルドしてアセンブリを作成。
A別のプロジェクトを作成しデフォルトの名前空間に
 @で作成した構造体と同じ名前を定義しビルドしてアセンブリを作成。
Bさらに別のプロジェクト(C#)にて@で作ったアセンブリと
 Aで作ったアセンブリをDLL参照して、Aの名前空間をUSINGする。
上記手順で、名前空間にアクセスできなくなっていることが確認できると思います。


質問内容としては以下の2点です。

@VBとC#では名前空間或いは保護レベルの扱いに違いがあるのか。
A別アセンブリのinternalなクラスと、名前空間が競合するのは
 正しい動きなのか。またそれを確認するために、あらかじめ
 参照するアセンブリの隠蔽されたメンバをリフレクションを
 使用して調べておくことがC#でプログラムを組む上で前提
 とされているのか。
 

よろしくお願いします。



[ メッセージ編集済み 編集者: ハニワ祭り 編集日時 2005-11-16 00:27 ]
sia
常連さん
会議室デビュー日: 2004/05/02
投稿数: 38
投稿日時: 2005-11-16 00:37
こんばんわです。

なにをもって独自というのかは意味が少し不明瞭だとは思いますが・・・。
VBとC#が仕様が違うのは当たり前だと思いますので。

で、本題ですが、ルートの名前空間というのは、
C#におけるグローバル名前空間のことでしょうか?

http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/csspec/html/CSharpSpecStart.asp
によると、あいまいな型宣言になり、エラーとなると思います。

基本的にはグローバル名前空間は禁じ手のはずなので、
MSDN内の”名前付けのガイドライン”に従って名前空間を整理することを
オススメします。(いろいろな事情で難しいのかもしれませんが・・・)
ハニワ祭り
大ベテラン
会議室デビュー日: 2005/11/15
投稿数: 115
投稿日時: 2005-11-16 01:14
siaさん返信ありがとうございます。

そうですグローバル名前空間のことです。用語が正確でなく申し訳ありません。
siaさんのおっしゃられるとおり
私も共用するアセンブリのグローバル名前空間を使うこと自体が
禁じ手だとは思いますが、internalでも問題になるのが理解できません。
通常では外からアクセスできないクラスと、名前空間が衝突するのを避けるのは
困難な気がするからです。

また、今回問題になったグローバル名前空間を使用しているのは、
VS.NET2003にバンドルされているクリスタルレポートのアセンブリ
・CrystalDecisions.CrystalReports.Engine
でした。

マイクロソフトが自ら禁じ手を行っているようなモジュールを
バンドルして販売しているとは思いたくないのですが‥


[ メッセージ編集済み 編集者: ハニワ祭り 編集日時 2005-11-16 01:17 ]
sia
常連さん
会議室デビュー日: 2004/05/02
投稿数: 38
投稿日時: 2005-11-16 08:17
おはようございます。

ハニワ祭りさんの仰る状況を試してみました。
たしかにアクセシビリティが無い旨のエラーメッセージで
ビルドできないですね・・・。
(一応確認ですが、発生している状況は
名前空間の名前と構造体名の衝突でしょうか?)

usingディレクティブにおける名前空間の解決方法について
詳しく調べることができていないので、回答ではないのですが、
C#の仕様をすこし読んだ限りでは、
ビルドできてもおかしくは無いような気もしますね。
(ただすこし読んだ限りではusingの名前解決にアクセシビリティが制限を与える
旨の記述は見あたりませんでしたが)。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-11-16 10:01
こんにちは。

ん〜試してみましたがならないです・・・。
引用:

Bさらに別のプロジェクト(C#)にて@で作ったアセンブリと
 Aで作ったアセンブリをDLL参照して、Aの名前空間をUSINGする。
上記手順で、名前空間にアクセスできなくなっていることが確認できると思います。


ここの、「Aの名前空間をUSINGする。」をしない状態だと、sia さんが仰った状況と同じにはなりますが、using しておくと普通に使えてます。
具体的なサンプルコードを教えてもらえませんか?
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-11-16 10:51
引用:

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

ん〜試してみましたがならないです・・・。


私もなりませんでした。
C# も VB もインポートした名前空間を優先してコンパイルします。

引用:

ここの、「Aの名前空間をUSINGする。」をしない状態だと、sia さんが仰った状況と同じにはなりますが、


2 を using していないのであれば、コンパイラは 1 の構造体であると認識しますよね?
1 は internal なので、アクセスできない保護レベルの警告になるハズです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
sia
常連さん
会議室デビュー日: 2004/05/02
投稿数: 38
投稿日時: 2005-11-16 19:03
こんばんわ。

こちらで試したC#のソースを参考までに。
アセンブリ1-----
※グローバルスコープ
internal struct NoNameClass
{
public void NoNameMethod(){}
}

end-----


アセンブリ2-----

namespace NoNameClass
{
public struct NoNameClass2
{
public void NoNameMethod(){}
}
}

end-----
アセンブリ3(アプリ)-----
using System;
using NoNameClass;

public class App{
}
end-----

読み違えているかもしれませんので
ハニワ祭りさんお願いします。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-11-16 19:32
 出ましたよ。

ファイル名で宣言された namespace '名前空間名' および class 'クラス名'は、名前空間'<Default>'で競合しています。

ms-help://MS.MSDNQTR.2003FEB.1041/vblr7/html/vbc30175namespaceconflict5.htm
もっとも、VB.NET で定義したとたん、タスク一覧に表示されましたので、C# のプロジェクトを作って云々まではいっていませんが。
 んで、混乱の元なので、エラーメッセージは端折ったり解釈したりせず、出ているまま正確に転写してくださいね。

 んで、要望としては、

internal なんだから、外部からは使えないのだから、外部で同じ名前を宣言しても良いじゃない

ってことでしょうか。

 internal だろうが private だろうが、「アクセスできない」というメッセージが出る以上、「存在していること」はわかっているわけです。「使えない」ことと、「存在していることがわからない」は違います。「存在していることがわかる」以上、名前がかぶることは出来ません。
 ん〜、「リフレクション」まわりを調べてみてください。private なメンバでも、アクセスできるようになりますから。
___________________________________________________________________
□ written by Jitta on 2005/11/16
□ Microsoft MVP for Visual Developer ASP/ASP.NET Oct.2005-Sept.2006
_________________

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