如何将菜单选项与vb.net中的函数关联?

huangapple go评论121阅读模式
英文:

How should I relate menu choices to functions in vb.net?

问题

我是您的中文翻译,以下是您要翻译的内容:

Dim fh128 As FarmHash128 = New FarmHash128
Dim fh32 As FarmHash32 = New FarmHash32
Dim fh64 As FarmHash64 = New FarmHash64

Private ReadOnly AlgoDict As New Dictionary(Of String, Object)() From {
    {"FarmHash128", fh128},
    {"FarmHash32", fh32},
    {"FarmHash64", fh64}
}

但这似乎不正确,也没有让我更接近解决方案。非常感谢任何帮助。谢谢!

编辑:
我已经有了一些进展;我提供的示例需要在字典中对算法实例进行New实例化。

AlgoDict = New Dictionary(Of String, Object) From {
    {"FarmHash128", New FarmHash128},
    {"FarmHash32", New FarmHash32}
}

这对我来说似乎不是一个好主意,因为AlgoDict中有更多的算法;当字典实例化时,是否会创建每个算法的实例?还是只有在我使用一个算法时才会创建实例?这似乎还阻止我在使用实例时包括参数:

Private CurrentA as Object
Private AlgoDict

AlgoDict = New Dictionary(Of String, Object) From {
    {"FarmHash128", New FarmHash128},
    {"FarmHash32", New FarmHash32}
}

Public Function Update(a As String, Optional s As ULong = 2088398552) As Object
    ' 在这里任何地方包括's'参数似乎会失败;是否可以更新实例的参数?
    Return AlgoDict.Item(a)
End Function

CurrentA = Update("FarmHash128", 123456)
英文:

I'm brand new to working with vb.net, so please excuse what you're about to read. I'm not looking for a particular solution, more for some vague guidance so I can come to a solution on my own. This is not homework, that's just how I learn best.

I need a dropdown that picks what hash algorithm to use to hash a file. I'm hung up on how to relate what is chosen to the use of that class. Ideally, I would use whatever libraries were available to the application to populate the menu, but am still not sure how I'd go from there to using one.
My thought then was to use a dictionary where the keys were the options and the class was the value, but this doesn't appear to be possible (at least using reflection, I don't think).

Below is a rough idea of what I'm trying; again, not looking for corrections on my code or a flat out solution, but would love to know what you all are doing for situations like this.

Dim fh128 As FarmHash128 = New FarmHash128
Dim fh32 As FarmHash32 = New FarmHash32
Dim fh64 As FarmHash64 = New FarmHash64

Private ReadOnly AlgoDict As New Dictionary(Of String, Object)() From {
    {"FarmHash128", fh128},
    {"FarmHash32", fh32},
    {"FarmHash64", fh64}
}

But that doesn't seem right, nor does it get me any closer. I greatly appreciate any help. Thanks!

Edit:
I did get somewhere; the example I gave needed the algorithm instances New'ed in the dictionary.

AlgoDict = New Dictionary(Of String, Object) From {
    {"FarmHash128", New FarmHash128},
    {"FarmHash32", New FarmHash32}
}

This seems like not a great idea to me, because there are many more algorithms in AlgoDict; when the dictionary is instantiated, does it create an instance of each? Or is this done only once I use one? This also appears to prevent me from including arguments when I do use one:

Private CurrentA as Object
Private AlgoDict

AlgoDict = New Dictionary(Of String, Object) From {
    {"FarmHash128", New FarmHash128},
    {"FarmHash32", New FarmHash32}
}

Public Function Update(a As String, Optional s As ULong = 2088398552) As Object
    ' including 's' as an argument anywhere here seems to fail; is it possible to update an instance's parameters?
    Return AlgoDict.Item(a)
End Function

CurrentA = Update("FarmHash128", 123456)

答案1

得分: 1

我相信我理解了您想要的内容。以下是已经翻译好的部分:

I believe I understand what you're looking for. Here is one such approach.

You could start with a class like this:-

The above class represents a choice of a hash function. It is an abstract class that is meant to be used to implement different hash functions with a common interface. This means would be able to swap out one for the other with almost no changes to the code that performs the hashing.

Using the above class, you could then implement specific hash functions like this:-

The above represents two implementations of HashChoice, one for MD5 and one for SHA256.

The nice thing about having a common abstract class, is that it makes it easy to discover them through reflection. You could add a static method to HashChoice like this:-

The above function will automatically discover every HashChoice class in the current assembly and create an instance of each. Now that function doesn't have to be a static member of the HashChoice class. You could put that anywhere you want in your application.

Now here is some test code that shows how all this could be used:-

The above code will find all the HashChoice classes defined in the assembly, create instances from these classes and use each one to hash a String. This is the output:-

If I decided to add more hash functions through more HashChoice-based classes, the above code would not need to be changed. They will automatically be discovered.

英文:

I believe I understand what you're looking for. Here is one such approach.

You could start with a class like this:-

Public MustInherit Class HashChoice

    Public MustOverride ReadOnly Property DisplayName As String

    'A convenience method to hash strings. You could add as many
    'such methods as you want. For example, to hash a FileStream
    Public Function HashString(ByVal s As String) As String
        Return HashData(Text.Encoding.UTF8.GetBytes(s))
    End Function

    Public Function HashData(ByVal data As Byte()) As String
        'Convert to Hex
        Return String.Join("", From b In InternalHashData(data) Select b.ToString("X2"))
    End Function

    'You are meant to override this to perform hashing. 
    'It is meant to take the data you want to hash 
    'as a byte array and return the hash digest as a byte array
    Protected MustOverride Function InternalHashData(ByVal data As Byte()) As Byte()

    'Makes sure it displays the name of the hash function 
    'when added to controls like ListBoxes or Comboboxes
    Public Overrides Function ToString() As String
        Return Me.DisplayName
    End Function

End Class

The above class represents a choice of a hash function. It is an abstract class that is meant to be used to implement different hash functions with a common interface. This means would be able to swap out one for the other with almost no changes to the code that performs the hashing.

Using the above class, you could then implement specific hash functions like this:-

Public Class HC_MD5
    Inherits HashChoice
    Public Overrides ReadOnly Property DisplayName As String
        Get
            Return "MD5"
        End Get
    End Property

    Protected Overrides Function InternalHashData(data() As Byte) As Byte()
        Using m = MD5.Create()
            Return m.ComputeHash(data)
        End Using
    End Function
End Class

Public Class HC_SHA256
    Inherits HashChoice
    Public Overrides ReadOnly Property DisplayName As String
        Get
            Return "SHA256"
        End Get
    End Property

    Protected Overrides Function InternalHashData(data() As Byte) As Byte()
        Using m = SHA256.Create()
            Return m.ComputeHash(data)
        End Using
    End Function
End Class

The above represents two implementations of HashChoice, one for MD5 and one for SHA256.

The nice thing about having a common abstract class, is that it makes it easy to discover them through reflection. You could add a static method to HashChoice like this:-

'I like putting static methods of a class in their own partial
'class. This is my personal taste. You don't have to do it
'this way
Partial Public MustInherit Class HashChoice

    Public Shared Function GetHashChoices() As HashChoice()
        Return (From t In Assembly.GetExecutingAssembly.GetTypes
                Where Not t.IsAbstract AndAlso GetType(HashChoice).IsAssignableFrom(t)
                Select DirectCast(Activator.CreateInstance(t), HashChoice)).ToArray
    End Function

End Class

The above function will automatically discover every HashChoice class in the current assembly and create an instance of each. Now that function doesn't have to be a static member of the HashChoice class. You could put that anywhere you want in your application.

Now here is some test code that shows how all this could be used:-

        Dim stringToHash As String = "Hello world!"

        'Find all the HashChoice objects in this assembly
        For Each hc As HashChoice In HashChoice.GetHashChoices()

            'Hash the String using the current instance of HashChoice
            Dim hash As String = hc.HashString(stringToHash)

            'Print the name of the hash function as well as
            'the hash digest produced by the hash operation
            Debug.WriteLine($"Hash function = {hc.DisplayName.PadRight(10)} Hash digest = {hash} ")

        Next

The above code will find all the HashChoice classes defined in the assembly, create instances from these classes and use each one to hash a String. This is the output:-

Hash function = MD5        Hash digest = 86FB269D190D2C85F6E0468CECA42A20 
Hash function = SHA256     Hash digest = C0535E4BE2B79FFD93291305436BF889314E4A3FAEC05ECFFCBB7DF31AD9E51A 

If I decided the add more hash functions through more HashChoice based classes, the above code would not need to be changed. They will automatically be discovered.

huangapple
  • 本文由 发表于 2023年3月12日 09:27:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75710586.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定