我想问一下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
答案 0 :(得分: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
答案 1 :(得分: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()
答案 2 :(得分:0)
如果序列的长度是固定的,你可以使用fixed
数组声明来保存它,但是固定数组需要“不安全”的代码,这在某些情况下可能会有问题。
否则,结构实际上没有很好的方法来封装具有值语义的非固定集合。如果希望结构传达用可变值语义封装集合的错觉,则必须使结构保持对数组或其他数据类型的私有引用,一旦引用存储到struct字段中,该数据类型将永远不会改变。如果要求结构更改包含的数据,则必须创建一个封装已更改数据的新对象。请注意,必须在存储引用之前进行任何更改。
使结构提供可变值语义的另一个困难是,没有任何方法可以通过该方法在结构上的实例方法可以指示它们是否可以安全地用于只读结构实例。实际上,在只读结构实例上不能使用任何结构方法或属性,但如果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);