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 Analyzer 抱怨我没有在 SELECT...CASE 的每个实例中处理对象。因此,如果用户提供“SHA1”作为算法类型,则哈希将设置为新SHA1Managed对象。为什么我需要处置SHA256Managed从未创建的 New 类?

但是......如果我只是在过程结束时处理散列对象:

hash.dispose()

分析器抱怨我没有处理SHA1Managed, SHA256Managed, SHA384Managed,SHA512ManagedMD5CryptoServiceProvider对象...其中 4 个无论如何都没有创建...

我不能使用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 Analyzer 希望我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

现在,也就是说,我认为您并不完全理解 case 语句,因为没有创建多个对象,只有一个,因为只有一个 case 语句会匹配。

也就是说,如果您愿意,这是可以通过转换器运行的 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 回答
1

你能做这样的事情吗...

Public Shared Function HashMe(ByVal plainText As String, ByVal hash2use As String) As Byte()
    Dim returnHash As Byte()
    Select Case hash2use.ToUpper
        Case "SHA1"
            Using (HashAlgorith hashAlgorith = new HashAlgorith())
                returnHash = hashAlgorith.ComputeHash(Encoding.UTF8.GetBytes(plainText))
            End Using
        ... do the same for the other cases ...
    End Select
    Return returnHash
End Function
于 2013-07-12T00:40:50.017 回答