我正在尝试创建一个不变的结构。问题是,它内部包含可变对象。是否可以使这些不可变(不修改其类)?例如(https://dotnetfiddle.net/KTiTzB):
function takeTheDetails($categoryName){
$option_arr = array_column($items,$categoryName);
function generate_option($item, $key)
{
echo "<option>" . $item . "</option>";
}
$options = array_unique($option_arr[0], SORT_NUMERIC); // You can add array_unique and SORT_NUMERIC here
asort($options);
echo "<select>";
array_walk_recursive($options, 'generate_option');
echo "</select>";
};
takeTheDetails('diametru');
是否有一种方法可以使IntHolder成员不可变,同时不修改IntHolder类?
答案 0 :(得分:1)
实际上是一个大问题:如何处理不可变数据中的嵌套对象?
https://softwareengineering.stackexchange.com/questions/279580/how-to-make-complex-objects-immutable
https://redux.js.org/recipes/structuringreducers/immutableupdatepatterns
我认为,创建不可变的子代模型以确保整个对象不可变是值得的。
请参见以下代码中的注释:
public class IntHolder
{
public int X
{
get;
set;
}
public ImmutableIntHolder ToImmutable()//convert itself to ImmutableIntHolder
{
return new ImmutableIntHolder(X);
}
}
public class ImmutableIntHolder
{
public ImmutableIntHolder(int x)
{
X = x;
}
public int X
{
get;
private set;
}
public IntHolder ToIntHolder() //convert it back to mutable IntHolder
{
return new IntHolder()
{
X = this.X
};
}
}
public struct ImmutableStruct
{
public int ImmutableInt
{
get;
private set;
}
public ImmutableIntHolder IntHolder //use ImmutableIntHolder instead
{
get;
private set;
}
public ImmutableStruct(int immutableInt, IntHolder myIntHolder) : this()
{
ImmutableInt = immutableInt;
IntHolder = myIntHolder.ToImmutable(); // convert to immutable
}
}
另一个选择是:
public class IntHolder
{
public int X
{
get;
set;
}
}
public class ImmutableStruct //changed to class
{
public int ImmutableInt
{
get;
private set;
}
public ImmutableIntHolder IntHolder
{
get;
private set;
}
public ImmutableStruct(int immutableInt, IntHolder myIntHolder) //: this()
{
ImmutableInt = immutableInt;
IntHolder = new ImmutableIntHolder(myIntHolder); // convert here.
}
public class ImmutableIntHolder
{
public ImmutableIntHolder(IntHolder intHolder)
{
//map all properties
X = intHolder.X;
}
public int X
{
get;
private set;
}
}
}