10

C# で記述されたいくつかの拡張メソッドを含むクラス ライブラリと、VB で記述された古い Web サイトがあります。

VB コードから拡張メソッドを呼び出したいのですが、それらが intelisense に表示されず、サイトにアクセスするとコンパイル エラーが発生します。

同じ名前空間に含まれる他のクラスが Intelisense で正常に表示されるため、必要なすべてのImportを取得しました。

助言がありますか

編集:いくつかのコメントに役立つ詳細情報。

私の実装は次のようになります

//C# code compiled as DLL
namespace x.y {
    public static class z {
        public static string q (this string s){
             return s + " " + s;
        }

    }
}

そして、このような私の使用法

Imports x.y

'...'
Dim r as string = "greg"
Dim s as string = r.q() ' does not show in intelisense
                        ' and throws error : Compiler Error Message: BC30203: Identifier expected.
4

10 に答える 10

8

いくつかの癖がありますが、それは私にとってはうまくいきます。まず、.NET 3.5 を対象とする C# クラス ライブラリを作成しました。プロジェクト内の唯一のコードは次のとおりです。

using System;

namespace ExtensionLibrary
{
  public static class Extensions
  {
    public static string CustomExtension(this string text)
    {
      char[] chars = text.ToCharArray();
      Array.Reverse(chars);
      return new string(chars);
    }
  }
}

次に、.NET 3.5 をターゲットとする VB コンソール アプリを作成し、C# プロジェクトへの参照を追加しました。Module1.vb の名前を Test.vb に変更しました。コードは次のとおりです。

Imports ExtensionLibrary

Module Test

    Sub Main()
        Console.WriteLine("Hello".CustomExtension())
    End Sub

End Module

これはコンパイルして実行します。(私はメソッド Reverse() を呼び出していたでしょうが、VB が魔法のようにすでにどこかでリバース機能を持っているかどうかはわかりませんでした.私は長いチョークで VB の専門家ではありません.)

最初は、Intellisense からのインポートとして ExtensionLibrary は提供されませんでした。ビルド後も「Imports ExtensionLibrary」はグレー表示され、電球はおそらく冗長なインポートを削除する機会を提供します。(そうすると、プロジェクトが壊れます。) これは、Visual Studio ではなく ReSharper である可能性があります。

要するに、それは実行可能であり、問​​題なく動作するはずです。古いバージョンの VB を使用している、またはプロジェクトが .NET 3.5 をターゲットにしていないことが問題だとは思いませんか?

コメントに記載されているように、追加の癖が 1 つあります。それは、ターゲットのコンパイル時の型がObject.

于 2008-10-17T19:03:28.267 に答える
2

わかった。エラー メッセージに基づいて、間違いなく最新の VB バージョン (VB 9!) を使用していないか、メソッドが見つからない場合に別のエラーが発生するため、エラーはこの問題とはまったく関係ありません。

エラー 1 'q' は 'String' のメンバーではありません。

于 2008-10-17T18:46:19.453 に答える
2

拡張メソッドは、静的メソッドのシンタックス シュガーにすぎません。そう

public static string MyExtMethod(this string s)

VB.NET と C# の両方で呼び出すことができます。

MyExtMethod("myArgument")
于 2008-10-17T17:30:38.733 に答える
1
Imports x.y

'...'
Dim r As String = "greg"
Dim s As String = r.q() 'same as z.q(r) 
于 2008-10-17T18:40:25.240 に答える
1

私は同様の問題に遭遇したと思います。VB.Netは拡張メソッドを介してコンパイルし、Option Strictオフの場合は実行時に推測されるようにしておくことを非常に喜んでいます。

ただし、VB.Netは、基本的な型の拡張メソッドを実際には好まないようです。次の場合、拡張することObjectはできず、解決することもできません。

C#

namespace NS
...

public static class Utility {

    public static void Something(this object input) { ...

    public static void Something(this string input) { ...

}

// Works fine, resolves to 2nd method
"test".Something();

// At compile time C# converts the above to:
Utility.Something("test");

ただし、これはVB.Netではうまくいきません。

Option Infer On
Option Explicit On
Option Strict Off
Imports NS
...

    Dim r as String = "test" 
    r.Something()

Somethingこれはエラーなしでコンパイルされますが、はメソッドではないため、実行時に失敗しますString-コンパイラは、拡張メソッドの構文糖衣をへの静的呼び出しに置き換えることができませんでしたUtility.Something

問題はなぜですか?C#とは異なり、 VB.Netは!への拡張子を処理できません。ObjectC#の有効な拡張メソッドは、VB.Netコンパイラを混乱させます。

一般的なVB.Netの規則として、基本的な.Netタイプ(、、、など)のいずれかで拡張メソッドを使用することはObject避けStringますInteger。またOption Infer、Visual Studioではデフォルトでオンになっていますが、コマンドラインコンパイルではデフォルトでオフになっているためVBCodeProvider、Webサイト(web.configによって異なります)ではオフになる場合があるため、注意する必要があります。オフの場合、VB.Netのすべてがと見なされObject、すべての拡張メソッドは実行時まで残されます(したがって失敗します)。

MicrosoftがVB.Netに拡張メソッドを追加したとき、本当にボールを落としたと思います。C#との一貫性を保つために試みた(そして失敗した)のは後からの考えだったと思います。

于 2012-08-31T08:08:38.663 に答える
0

チェックする2つのこと:

  1. .Net3.5をターゲットにしています
  2. DLLを参照しています

一部のツールは、それらをサポートしていないプロジェクトの拡張メソッドを誤って提案する場合があります。

于 2008-10-17T19:21:19.383 に答える
0

…そしてVBで書かれた古いウェブサイト。

ここでの「古い」とは、おそらくここで古いバージョンのVBも使用していることを意味しますか?とにかく、拡張メソッドは属性で装飾された単なるバニラ静的(「<code> Shared」)メソッドであるため、どのような場合でもそれらを呼び出すことができるはずです。

これが不可能な場合は、古いバージョンのVBでそれらを「拡張スタイル」と呼ぼうとするか、間違ったバージョンのC#アセンブリを参照しています。

編集:名前空間全体Importを使用していることを確認しますか?つまり、名前空間だけではありませんか?VBはC#よりも簡単にネストされた名前空間にアクセスできるため、VBで次のコードを使用して名前空間のクラスを使用できます。ただし、拡張メソッドを機能させるには、フルパスを編集する必要があります。x.yxx.yImport

Imports x
Dim x As New y.SomeClass()
于 2008-10-17T18:33:14.847 に答える
0

私は同じ問題に遭遇し、誤って解決策に出くわした可能性があります. 私が使用した場合

x.y.r.q()

、それは私にも同じエラーを投げました。しかし、xy をインポートすると、うまくいきました。

using x.y;
...
r.q()

無事だった。

したがって、それを機能させるには、宣言にインポートする必要があるようです。

于 2010-09-18T14:39:05.110 に答える
0

C# と同じドット表記で呼び出すことができるかどうかはわかりませんが、静的拡張メソッドは拡張型として最初の引数を持つ静的関数として表示されると思います。したがって、VB で実際にクラスを呼び出すことができるはずです。

StaticClass.ExtensionMethod(theString, arg1, ..., argN)

C# では、次のように記述します。

theString.ExtensionMethod(arg1, ..., argN);

StaticClass は、拡張メソッドを定義した静的クラスの名前です。

于 2008-10-17T17:31:37.030 に答える
-1

これはかなり前のことで、どのように解決したかはわかりませんが、言うまでもなく、ユーザー エラーでした。おそらくコンピューターを再起動したところ、消えてしまいました。

于 2009-02-07T15:42:13.793 に答える