.NET 2.0 を対象とする VS 2012 RC VB.NET プロジェクトで非常に奇妙な状況が発生しています。何らかの理由で、Get メソッドに加えてプロパティの Set メソッドが呼び出されます。
これは期待どおりに機能します。
Dim _searchparray = New Byte() {37, 115, ...}
Dim rep() As Byte = _opt.ReplaceBytes
If Arrays.CompareTo(rep, _searchparray, 1, False) = -1 AndAlso _opt.SearchMatchPlaceholderInReplaceBytes Then ...
つまり、_opt.ReplaceBytes の Get メソッドは 1 回だけ呼び出され、Set メソッドは呼び出されません。
しかし、これは機能しません:
Dim _searchparray = New Byte() {37, 115, ...}
If Arrays.CompareTo(_opt.ReplaceBytes, _searchparray, 1, False) = -1 AndAlso _opt.SearchMatchPlaceholderInReplaceBytes Then ...
ここでは、最初に _opt.ReplaceBytes の Get メソッドが呼び出され、次に Arrays.CompareTo が返され、次に _opt.ReplaceBytes の Set メソッドが呼び出されます。なんで?コール スタックは、呼び出し元が上記のサンプルの最後の行であることを示しています。しかし、プロパティをどこに設定するのでしょうか? 関数が値を返した後に Set メソッドが呼び出されるため、Arrays.CompareTo に含めることはできず、_opt.SearchMatchPlaceholderInReplaceBytes の Get メソッドを介して設定することもできません。
この奇妙な動作について説明できる人はいますか? ありがとう。
これを示すサンプル プロジェクト全体を次に示します。
Imports System.Runtime.CompilerServices
Module Module1
Sub Main()
Dim _opt As New Opts
Dim _searchparray = New Byte() {37, 115}
If Arrays.CompareTo(_opt.ReplaceBytes, _searchparray, 1, False) = -1 AndAlso _opt.SearchMatchPlaceholderInReplaceBytes Then
Console.WriteLine("0")
End If
Console.WriteLine("1")
End Sub
End Module
Module Arrays
<Extension()> _
Friend Function CompareTo(Of T As IEquatable(Of T))(ByRef SearchArray() As T, ByRef AnotherArray() As T, ByRef aWildCardElement As T, Optional aUseWildcards As Boolean = True) As Integer
Dim min As Integer = If(SearchArray.Length < AnotherArray.Length, SearchArray.Length, AnotherArray.Length) - 1
If aUseWildcards AndAlso aWildCardElement IsNot Nothing Then
For i = 0 To min
If SearchArray(i).Equals(aWildCardElement) Then Continue For
If Not SearchArray(i).Equals(AnotherArray(i)) Then Return i
Next
Else
For i = 0 To min
If Not SearchArray(i).Equals(AnotherArray(i)) Then Return i
Next
End If
If SearchArray.Length = AnotherArray.Length Then
Return -1
Else
Return min + 1
End If
End Function
End Module
Public Class Opts
Private _ReplaceBytes() As Byte = New Byte() {}
<Xml.Serialization.XmlIgnore()> _
Public Property ReplaceBytes As Byte()
Get
Return _ReplaceBytes
End Get
Set(ByVal value As Byte())
_ReplaceBytes = value
End Set
End Property
Private _SearchMatchPlaceholderInReplaceBytes As Boolean = False
Public Property SearchMatchPlaceholderInReplaceBytes() As Boolean
Get
Return _SearchMatchPlaceholderInReplaceBytes 'Set breakpoint here
End Get
Set(ByVal value As Boolean)
'Set breakpoint here too
_SearchMatchPlaceholderInReplaceBytes = value
End Set
End Property
End Class
Namespace Global.System.Runtime.CompilerServices
<AttributeUsage((AttributeTargets.Method Or (AttributeTargets.Class Or AttributeTargets.Assembly))), System.Reflection.Obfuscation(ApplyToMembers:=True, Exclude:=True)> _
Public NotInheritable Class ExtensionAttribute
Inherits Attribute
Public Sub New()
End Sub
End Class
End Namespace