C# - 在结构中强制执行子对象不变性
C# - Enforce Child Object Immutability in Struct
我正在尝试创建一个不可变结构。问题是,它内部包含可变对象。是否可以使它们不可变(不修改它们的 class)?例如 (https://dotnetfiddle.net/KTiTzB):
public class IntHolder
{
public int X
{
get;
set;
}
}
public struct ImmutableStruct
{
public int ImmutableInt
{
get;
private set;
}
public IntHolder MyIntHolder
{
get;
private set;
}
public ImmutableStruct(int immutableInt, IntHolder myIntHolder): this ()
{
ImmutableInt = immutableInt;
MyIntHolder = myIntHolder;
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Immutability");
IntHolder intHolder = new IntHolder();
intHolder.X = 40;
Console.WriteLine(intHolder.X == 40); // TRUE
ImmutableStruct immStruct = new ImmutableStruct(10, intHolder);
Console.WriteLine(immStruct.ImmutableInt == 10); // TRUE
// immStruct.ImmutableInt = 4; // THIS DOESN'T WORK, AS EXPECTED. Hurray!
// immStruct.MyIntHolder = new IntHolder(3); // ALSO DOESN'T WORK, GOOD!
immStruct.MyIntHolder.X = 4; // how can I prevent this from working?
}
}
有没有办法在不修改 IntHolder class 的情况下使 IntHolder 成员不可变?
其实是个大问题:如何处理不可变数据中的嵌套对象?
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;
}
}
}
我正在尝试创建一个不可变结构。问题是,它内部包含可变对象。是否可以使它们不可变(不修改它们的 class)?例如 (https://dotnetfiddle.net/KTiTzB):
public class IntHolder
{
public int X
{
get;
set;
}
}
public struct ImmutableStruct
{
public int ImmutableInt
{
get;
private set;
}
public IntHolder MyIntHolder
{
get;
private set;
}
public ImmutableStruct(int immutableInt, IntHolder myIntHolder): this ()
{
ImmutableInt = immutableInt;
MyIntHolder = myIntHolder;
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Immutability");
IntHolder intHolder = new IntHolder();
intHolder.X = 40;
Console.WriteLine(intHolder.X == 40); // TRUE
ImmutableStruct immStruct = new ImmutableStruct(10, intHolder);
Console.WriteLine(immStruct.ImmutableInt == 10); // TRUE
// immStruct.ImmutableInt = 4; // THIS DOESN'T WORK, AS EXPECTED. Hurray!
// immStruct.MyIntHolder = new IntHolder(3); // ALSO DOESN'T WORK, GOOD!
immStruct.MyIntHolder.X = 4; // how can I prevent this from working?
}
}
有没有办法在不修改 IntHolder class 的情况下使 IntHolder 成员不可变?
其实是个大问题:如何处理不可变数据中的嵌套对象?
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;
}
}
}