2009-05-05 19 views
8

VB.NetでコンストラクタORDERが重要なのはなぜですか?私は基本的なCOMライブラリを完全に包むようになっている.Netタイプのライブラリを構築していますので、APIのコンシューマはCOMライブラリの代わりに.Netコレクションとその他の.notライブラリを使用するふりをすることができます。VB.Netコンストラクタの順序は重要ですか?

現在のところ、ほとんどのクラスは、ReflectionとCodeDOMを使用して構築された1〜1ラッパーです。これらのクラスには、基になるCOM型をパラメータとして持つ内部コンストラクタがあります。 CodeDOMは、これをクラスの最初のコンストラクタとして構築します。 C#のこれらのクラスを使用することは問題ありません。私が必要とするのは.Netライブラリへの参照であり、すべて正常です。

これらのクラスをVB.Netプロジェクトから使用しようとすると問題が発生します。最初のコンストラクターがCOM型を引数として持つ場合、VB.NetプロジェクトにはCOM相互運用機能アセンブリが参照として必要です。最初のコンストラクタに引数がない場合やマネージ型しかない場合は、すべて正常に動作します。私のクラスライブラリはC#で書かれています。

次作品:

public class ObjectID 
{ 
    public ObjectID(int type, int id) 
    { 
     this.Type = type; 
     this.ID = id; 
    } 

    internal ObjectID(COMLib.ObjectID id) : this(id.Type, id.ID) { } 

    public int ID { get; set; } 
    public int Type { get; set; } 

    internal COMLib.ObjectID ToCOM() 
    { 
     COMLib.ObjectID id = new COMLib.ObjectID(); 
     id.ID = this.ID; 
     id.Type = this.Type; 
     return id; 
    } 
} 

以下はCOMLib.Interopアセンブリへの参照が必要です。

public class ObjectID 
{ 
    internal ObjectID(COMLib.ObjectID id) : this(id.Type, id.ID) { } 

    public ObjectID(int type, int id) 
    { 
     this.Type = type; 
     this.ID = id; 
    } 

    public int ID { get; set; } 
    public int Type { get; set; } 

    internal COMLib.ObjectID ToCOM() 
    { 
     COMLib.ObjectID id = new COMLib.ObjectID(); 
     id.ID = this.ID; 
     id.Type = this.Type; 
     return id; 
    } 
} 

今私は、これらのクラスにダミープライベートコンストラクタを作成することによってこの問題を解決することができます最初のコンストラクタですが、これを引き起こす原因についてもっと興味がありますか? VB.Netでコンストラクタ宣言の順序が重要なのはなぜですか?

更新

これは私がそれを自分自身を疑う始めたように非常識聞こえました。 3つのプロジェクトでそれを複製することができました。

C#クラスライブラリ:

namespace Wrapped 
{ 
    public class Class1 
    { 
    } 
} 

C#クラスライブラリをラップ:ラッパー

namespace Wrapper 
{ 
    public class Class1 
    { 
     internal Class1(Wrapped.Class1 c) { } 
     public Class1() { } 
    } 
} 

VB.Netコンソールアプリ:ラッパーがラップ リファラーを指し

Module Module1 
    Sub Main() 
     Dim w As New Wrapper.Class1 
    End Sub 
End Module 

リファラを指し、ラッパー リファラーは参照していないラップされた

Dim w As New Wrapper.Class1 

は、コンストラクタの順序を入れ替えエラー

Reference required to assembly 'Wrapped, Version=1.0.0.0, 
             Culture=neutral, 
             PublicKeyToken=null' 
containing the type 'Wrapped.Class1'. 
Add one to your project. 

は、エラーの世話を生成します。

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=442224

アップデート(私は簡単に確認することはできません)正しい場合は

Causes error:   No error: 

    Vb-ReferTest   Vb-RefererTest 
      |      |      Fixes error in Vb- 
      V      V      RefererTest even 
     Cs-Wrapper   Cs-Wrapper Vb-Wrapper <- if the Vb-Wrapper 
      |      \  /  and the RefererTest 
      V      V  V    have no direct 
    Cs-WrappedLibrary   Cs-WrappedLibrary   relationship 

答えて

1

いくつかのより多くの周りを再生した後、それがfasinatingされます。注文は問題ではありません、AFAIK。あなたがそれについて確信があるなら、おそらくlog as a bug on connect(サンプルコードあり)。

+0

もう一度自分自身を確認した後、簡単なサンプルコードを追加しました。 –

0

いいえ、コンストラクタのコード順(C#またはVB.NETを使用)の順序は関係ありません。

しかし、この特定のケース(私はそれをテストしていません)では、バグを見つけた可能性があります。 「自分のマシンでブレークする」という結論に達する前に、他の人に自分のマシンで問題を確認させたいと思うかもしれません。私は以前これが起こっていた。

+0

また、私の仕事用コンピュータをオフィスで壊す。それで、Vista 64bitとXP 32bitでテストされました。明日のテストを予定していましたが、あなたが言及して以来、RDesktopでやりました。 –

1

Confirmed as a bug.あまりにも価値があるように修正するのはあまりにも難しいので、私はちょうどそれと一緒に暮らしていると思います。幸運なことに、珍しいクラス設定のクロス言語プロジェクトが必要です。

+0

[接続]リンクのコメントとして回避策が提供されていますか? – SqlRyan

+0

はい、そうです。これは基本的に質問の最後の更新と同じものです。ラッパー・ライブラリーのソースを制御する場合、より簡単な回避策は、パラメータなしのデフォルト・コンストラクターを一番上に移動するか、Connectの回避策セクションに掲載されているパラメーターなしコンストラクターがない場合はプライベート・パラメーターを追加することです。これにより、将来のユーザーにも問題が解決されます。 –

関連する問題