39

(すべて)のすべてのサブクラスに対してExtensionメソッドを作成できますSystem.Objectか?

例:

<Extension>
Public Function MyExtension(value As Object) As Object
    Return value
End Function

上記の関数は、オブジェクトインスタンスでは機能しません。

Dim myObj1 As New Object()
Dim myObj2 = myObj1.MyExtension()

コンパイラはそれを受け入れません、私のコンピュータに問題がありますか?:)

UPDATE
この問題は、オブジェクトのメンバーがリフレクションによってルックアップされるVBでのみ発生するようです(レイトバウンド)。

回答後の更新
FYI、vbにはC#に欠けている利点があるため、インポートされたモジュールのメンバーはグローバルスコープにインポートされるため、ラッパーなしでこの関数を引き続き使用できます。

Dim myObj2 = MyExtension(myObj1)
4

6 に答える 6

45

オブジェクトで拡張メソッドをサポートしないことは、VBでの設計上の決定だったようです。

その結果、拡張メソッドが既存のレイトバウンドコードを完全に破壊するのを防ぐ唯一の方法は、オブジェクトとして入力されたものでそれらが使用されないようにすることでした。

http://blogs.msdn.com/b/vbteam/archive/2007/01/24/extension-methods-and-late-binding-extension-methods-part-4.aspx

于 2010-07-12T12:31:16.960 に答える
14

少し前に聞いたこの質問を参照してください。基本的に、必要に応じてVB.NETで拡張できます。 ただし、下位互換性の理由から、拡張メソッドを使用できるように宣言された変数はありません。これは、VB.NETがで遅延バインディングをサポートしているため、拡張メソッドにアクセスしようとする試みは無視され、問題のオブジェクトのタイプから同じ名前のメソッドを見つけようとするためです。 ObjectObjectObject

したがって、この拡張方法を例にとってみましょう。

<Extension()>
Public Sub Dump(ByVal obj As Object)
    Console.WriteLine(obj)
End Sub

この拡張方法は、ここで使用できます。

' Note: here we are calling the Dump extension method on a variable '
' typed as String, which works because String (like all classes) '
' inherits from Object. '
Dim str As String = "Hello!"
str.Dump()

しかし、ここではありません:

' Here we attempt to call Dump on a variable typed as Object; but '
' this will not work since late binding is a feature that came before '
' extension methods. '
Dim obj As New Object
obj.Dump()

dynamic拡張メソッドがC#の変数で機能しない理由を自問してみてください。そうすれば、説明が同じであることがわかります。

于 2010-07-12T12:58:23.360 に答える
13

Objectの拡張メソッドを直接作成することはできませんが、ジェネリックスを使用すると同じ結果を得ることができます。

<Extension()>
Public Function NullSafeToString(Of T)(this As T) As String
    If this is Nothing Then
       Return String.Empty
    End If
    Return this.ToString()
End Function

これは、Object型であると宣言されているものを除いて、すべての拡張メソッドとして呼び出すことができることに注意してください。それらの場合は、直接呼び出すか(完全な証明)、キャストを介して呼び出す必要があります(これは、統一されたインターフェイスがないため、失敗する可能性があります。

于 2015-07-23T00:35:08.500 に答える
1

jmorenoの答え はで使用できませんOption Strict On–エラーをスローします:

BC30512 Option Strict Onは、「オブジェクト」から「整数」への暗黙的な変換を許可しません。

クラスから拡張モジュールへのコンテキストスイッチが必要です。

Dim text1 As String = MyExtModule.NullSafeToString(DataGridView1.Rows(0).Cells(0).Value)
于 2015-09-08T12:48:09.137 に答える
0

確かに可能ですが、すべてのオブジェクトが乱雑にならないように、ここで行うことについては控えめにしたいと思うかもしれません。Objectに使用するのが好きな拡張メソッドは、SQL IN()ステートメントと同様に機能するIsIn()というメソッドです。次のようなことを言うのはいいことです:

If someString.IsIn("a", "b", "c") Then
   DoSomething()
Else If someInt.IsIn(1, 2, 3) Then
   DoSomethingElse()
Else If someObj.IsIn(1, "q", #7/1/2010#) Then
   DoSomethingTheThirdWay()
End If

編集 -

コメント投稿者を支援するために、以下にIsIn()拡張メソッドの実装を追加しました。

Imports System.Runtime.CompilerServices

Public Module ObjectExtensions
  <Extension()>
  Public Function IsIn(obj As Object, ParamArray values() As Object) As Boolean
    For Each val As Object In values
      If val.Equals(obj) Then Return True
    Next
    Return False
  End Function
End Module
于 2010-07-12T11:14:48.517 に答える
-5

オブジェクトインテリジェンスに対してあまりにも多くの拡張を行うと、役に立たなくなる可能性がありますが、それは完全に有効です。

オブジェクト情報のオブジェクトに対する拡張メソッドの例を次に示します。

http://www.developer.com/net/csharp/article.php/3718806/NET-Tip-Using-Extension-Methods.htm

于 2010-07-12T11:34:27.507 に答える