0

SELECT...CASE ステートメントを使用して、ユーザー入力に基づいてオブジェクトを作成するプロシージャがあります。

Dim hash As HashAlgorithm

' Make sure hashing algorithm name is specified.
If (hashAlgorithm Is Nothing) Then
    hashAlgorithm = ""
End If

' Initialize appropriate hashing algorithm class.
Select Case hashAlgorithm.ToUpper()
    Case "SHA1"
        hash = New SHA1Managed()
    Case "SHA256"
        hash = New SHA256Managed()
    Case "SHA384"
        hash = New SHA384Managed()
    Case "SHA512"
        hash = New SHA512Managed()
    Case Else
        hash = New MD5CryptoServiceProvider()
End Select

VS アナライザーは、SELECT...CASE の各インスタンスでオブジェクトを破棄していないと文句を言います。したがって、ユーザーがアルゴリズム タイプとして「SHA1」を指定した場合、ハッシュは新しいSHA1Managedオブジェクトに設定されます。SHA256Managed作成されていない New クラスを破棄する必要があるのはなぜですか?

しかし...手順の最後にハッシュオブジェクトを単純に破棄すると:

hash.dispose()

アナライザーは、、、、、およびオブジェクトSHA1Managedを破棄SHA256ManagedSHA384Managedていないと不平を言います...そのうち4つは作成されませんでした...SHA512ManagedMD5CryptoServiceProvider

ステートメントUsing hash as HashAlgorithm内でオブジェクトをインスタンス化する必要があるため、使用できません。Using

おそらく、コード アナライザーは単にNew <Object>ステートメントを対象としているだけで、私はクールだと思っていますが、意見を求めてここに来たかったのです...

編集: わかりました明らかに明確ではなかったので、ここでは非常にシンプルで小さく、完全な作業手順を示します。

Public Shared Function HashMe(ByVal plainText As String, ByVal hash2use As String) As Byte()
    Dim myHash As HashAlgorithm
    Select Case hash2use.ToUpper
        Case "SHA1"
            myHash = New SHA1Managed()
        Case "SHA256"
            myHash = New SHA256Managed()
        Case "SHA384"
            myHash = New SHA384Managed()
        Case "SHA512"
            myHash = New SHA512Managed()
        Case Else
            myHash = New MD5CryptoServiceProvider()
    End Select
    Return myHash.ComputeHash(Encoding.UTF8.GetBytes(plainText))
    myHash.Dispose()
End Function

この手順は問題なく機能しますが、VS アナライザーが、New <Object>呼び出されたものをすべて、SELECT CASE

Using ブロックでラップするという回答は無効であり、コンパイルされません。

4

3 に答える 3

4

それを行う最も簡単な方法は、最初にそれを using ブロックに入れて、関数でインスタンスを作成することです。HashAlgorithm には、まさにあなたがしていることを行うメソッドがあります。

vb.net の構文は覚えていませんが、次のようにします。

Using hash as HashAlgorithm = HashAlgorithm.Create(hashAlgorithm)
    ' use the algorithm here
End Using

独自のメソッドをロールしたい場合は、次のようになります

Public Shared Function CreateHashAlgorithm(ByVal hash as String)
    Select Case hash.ToUpper
        Case "SHA1"
            Return New SHA1Managed()
        Case "SHA256"
            Return New SHA256Managed()
        Case "SHA384"
            Return New SHA384Managed()
        Case "SHA512"
            Return New SHA512Managed()
        Case Else
            Return New MD5CryptoServiceProvider()
    End Select
End Function

次に、次のように使用します

Using hash as HashAlgorithm = CreateHashAlgorithm(algorithm)
    Byte() data = hash.ComputeHash(whatever)
End Using

そうは言っても、ケースステートメントを完全に理解しているとは思いません。作成されるオブジェクトは複数ではなく、1 つだけです。一致するケースステートメントは 1 つだけだからです。

そうは言っても、必要に応じてコンバーターを介して実行できるこれの c# バージョンを次に示します。

using (HashAlgorithm hash = HashAlgorithm.Create(algorithm))
{
    // use the algorithm
}

// if we want to make our own version of HashAlgorith.Create()
public HashAlgorithm CreateHashAlgorithm(string algorithm)
{
    algorithm = algorithm ?? "";
    switch(algorithm.ToUpper())
    {
        case "SHA1": return new SHA1Managed();
        case "SHA256": return new SHA256Managed();
        // and the rest
        default: return new MD5CryptoServiceProvider();
    }
}

// and to use it
using (HashAlgorithm hash = CreateHashAlgorithm(algorithm))
{
    byte[] data = hash.ComputeHash(whatever);
}
于 2013-07-12T00:08:19.663 に答える
1

関数について警告されている理由は、.Dispose() が呼び出される前に例外がスローされた場合、HashAlgorithm が Dispose()d にならないためです。

最も簡単な答えは、既に書いたものを保持して、次のように finally{} ブロックで Dispose() を呼び出すことです。

    Public Shared Function HashMe(ByVal plainText As String, ByVal hash2use As String) As Byte()
        Dim myHash As HashAlgorithm
try 
        Select Case hash2use.ToUpper
            Case "SHA1"
                myHash = New SHA1Managed()
            Case "SHA256"
                myHash = New SHA256Managed()
            Case "SHA384"
                myHash = New SHA384Managed()
            Case "SHA512"
                myHash = New SHA512Managed()
            Case Else
                myHash = New MD5CryptoServiceProvider()
        End Select
        Return myHash.ComputeHash(Encoding.UTF8.GetBytes(plainText))
end try 
finally
        myHash.Dispose()
end finally
End Function
于 2013-07-12T00:48:11.933 に答える