1

我想问一些关于 VB.NET 代码的问题。我深受这个问题的困扰。如果您知道我的问题的解决方案,请回答我或给我一些意见。


'Declare a structure "Gene"
    Public Structure Gene
    Dim Seq() As Integer
    End Structure

'Here is a procedure, it changes original value.
        Public Sub Mutation(ByVal OriginalGene As Gene, ByRef TargetGene As Gene)
        Dim P1 As Integer
        Dim P2 As Integer
        Dim Temp As Integer

        P1 = Int((N_Jobs - 1 + 1) * Rnd(RndNum) + 0)
        P2 = Int((N_Jobs - 1 + 1) * Rnd(RndNum + 1) + 0)

        TargetGene.Seq = OriginalGene.Seq

        Temp = TargetGene.Seq(P1)
        TargetGene.Seq(P1) = TargetGene.Seq(P2)
        TargetGene.Seq(P2) = Temp
        End Sub
4

3 回答 3

1

它实际上并没有改变结构。所有结构包含一个指向数组的指针。即使您可以拥有无​​限数量的结构副本,对数组的引用也始终相同。


不可变基因类的示例:

Public Class Gene
    Private _sequence() As Integer
    Public Sub New(sequence() As Integer)
        _sequence = sequence
    End Sub
    Public Function GetSequence() As Integer()
        Return _sequence.Select(Function (x) x).ToArray()
    End Function
    Public Function Mutate() As Gene
        Dim sequence() As Integer = Me.GetSequence()

        Dim P1 As Integer
        Dim P2 As Integer
        Dim Temp As Integer

        P1 = Int((N_Jobs - 1 + 1) * Rnd(RndNum) + 0)
        P2 = Int((N_Jobs - 1 + 1) * Rnd(RndNum + 1) + 0)

        TargetGene.Seq = OriginalGene.Seq

        Temp = sequence(P1)
        sequence(P1) = sequence(P2)
        sequence(P2) = Temp

        Return New Gene(sequence)
    End Function
End Class
于 2014-02-06T07:24:05.977 回答
0

如果序列的长度是固定的,您可以使用fixed数组声明来保存它,但固定数组需要“不安全”代码,这在某些情况下可能会出现问题。

否则,对于结构来说,用值语义封装非固定集合真的没有什么好方法。如果希望结构传达用可变值语义封装集合的错觉,则必须让结构持有对数组或其他数据类型的私有引用,一旦引用存储到结构字段中,该引用就永远不会改变。如果要求结构更改包含的数据,它必须创建一个封装更改数据的新对象。请注意,任何将要进行的更改都必须在存储参考之前进行。

让结构提供可变值语义的另一个困难是,没有任何方法可以通过结构上的实例方法来指示它们是否可以安全地用于只读结构实例。实际上,不能在只读结构实例上使用结构方法或属性,但如果 C# 看到,例如

 someObject.propertyOfStructType.doSomething();

它会默默地将代码重写为

 var temp = someObject.propertyOfStructType;
 temp.doSomething();

有时这种替代是安全的。有时不是。虽然编译器应该很容易检查一个方法是否被标记为“不用于只读结构”属性并拒绝使用这些方法进行上述替换,但没有记录用于此目的的属性。因此,如果想要提供一种安全的方法,例如将一系列值从数组复制到值数组类型,则必须编写并调用该方法,如下所示:

public static int LoadFromEnumerable(ref ValueArray<T> it, int startIndex, IEnumerable<T> source);

int numElementsAdded = ValueArray<int>.LoadFromEnumerable(ref myValueArray, 4, myIntegers);

与看起来更干净的相反

public int LoadFromEnumerable(int startIndex, IEnumerable<T> source);

myValueArray.LoadFromEnumerable(4, myIntegers);
于 2014-02-07T20:03:43.837 回答
0

您需要实现结构的副本,尝试类似:

    Structure Gene
    Dim Seq() As Integer
    Public Function Clone() As Gene
        Dim mySt As Gene
        Array.Copy(Me.Seq, mySt.Seq, Me.Seq.Length)
        Return mySt
    End Function
End Structure

然后代替:

TargetGene.Seq = OriginalGene.Seq

利用

TargetGene.Seq = OriginalGene.Clone()
于 2014-02-06T08:53:18.830 回答