如何dispose()在SELECT ... CASE语句中创建的对象?

时间:2013-07-11 23:59:15

标签: .net vb.net idisposable

我有一个使用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类?

但是......如果我只是在程序结束时处理哈希对象:

hash.dispose()

分析器抱怨我没有处理SHA1ManagedSHA256ManagedSHA384ManagedSHA512ManagedMD5CryptoServiceProvider个对象...其中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块中的答案无效,无法编译。

3 个答案:

答案 0 :(得分:4)

嗯,最简单的方法是将它放在一个使用块中,然后在函数中创建实例。 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);
}

答案 1 :(得分: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

答案 2 :(得分: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