- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在用 C#/WPF 编写一个相当大的应用程序。我使用 Builder 模式创建始终处于一致状态的对象,并且这些对象是不可变的。
我在这个设计中遇到了一个我不知道如何解决的问题。
考虑以下两个类:
public class Employee {
public string Name { get; }
public double Salary { get; }
public IReadOnlyList<EmployeeBonus> Bonuses { get; } // read-only list of bonuses
public Employee(string name, double salary, IEnumerable<EmployeeBonus> bonuses) {
Name = name;
Salary = salary;
Bonuses = new List<EmployeeBonus>(bonuses); // list of bonuses initialized in constructor
}
}
public class EmployeeBonus {
public Employee Employee { get; } // bonus has reference to Employee
public string Description { get; }
public double Amount { get; }
public EmployeeBonus(Employee employee, string description, double amount) {
Employee = employee; // employee must be initialized in constructor
Description = description;
Amount = amount;
}
}
所以 - 我有一个 Employee 类,其中包含每个员工收到的奖金列表。 EmployeeBonus 类包含对 Employee 的引用。由于这两个类都是不可变的,因此每个类都必须使用对另一个的引用进行初始化。但这当然是不可能的,因为我无法创建一个引用另一个不存在的对象的对象。
我想到的解决方案:
一个。我想过在EmployeeBonus中不要引用Employee,所以EmployeeBonus只需要构造Description和Amount。但这打破了我的存储库模式:我的 Repository<EmployeeBonus>
有一个仅接受 EmployeeBonus 的 Add 方法。为了正确保存这个对象,我需要知道哪个员工拥有它,并且因为该方法只接受一个 EmployeeBonus - 这个对象必须包含 Employee。
B.我考虑过向 Employee 添加一个 AddBonus(string description, double amount) 方法,这样奖金列表就不会在构造函数中初始化,而是稍后添加每个奖金并且 Employee 类将自身附加到每个奖金 - 但那会使 Employee 不再不可变。
C.我可以破坏我的通用存储库并创建另一个方法,Add(EmployeBonus bonus, Employee employee)
,然后从 EmployeeBonus 中删除 Employee - 但是我的 EmployeeBonusRepository 不会继承自 Repository<EmployeeBonus>
.
D.我能想到的最正确的解决方案(正确但非常浪费)是这样的:
public class Employee
{
public string Name { get; }
public double Salary { get; }
public IReadOnlyList<EmployeeBonus> Bonuses { get; }
public Employee(string name, double salary, IEnumerable<EmployeeBonus> bonuses) {
Name = name;
Salary = salary;
Bonuses = new List<EmployeeBonus>(bonuses);
}
}
public class EmployeeBonus
{
public string Description { get; }
public double Amount { get; }
public EmployeeBonus(string description, double amount) {
Description = description;
Amount = amount;
}
}
public class EmployeeBonusWithEmployee
{
public Employee Employee { get; }
public EmployeeBonus Bonus { get; }
public EmployeeBonusWithEmployee(Employee employee, EmployeeBonus bonus)
{
Employee = employee;
Bonus = bonus;
}
}
public class EmployeeBonusWithEmployeeRepository : Repository<EmployeeBonusWithEmployee>
{
public void Add(EmployeeBonusWithEmployee bonus)
{
// save complete employee bonus
}
}
public class EmployeeRepository : Repository<Employee>
{
//...
public void Add(Employee employee)
{
// saves employee first,
// then creates an EmployeeBonusWithEmployee object for each EmployeeBonus in the list
// and saves it using an EmployeeBonusWithEmployeeRepository
}
}
这个解决方案 (D) 是否有意义?有更优雅的方法吗?
最佳答案
要在 C# 中创建相互引用的对象,您需要延迟执行相互引用的代码 - 直到两个对象都已创建。
public class B
{
private Lazy<A> _a;
public A GetA
{
get { return _a.Value; }
}
public B(Lazy<A> forLater)
{
_a = forLater;
}
}
A类也一样。然后创建相互引用的对象:
A a = null;
B b = null;
a = new A(new Lazy<B>(() => b));
b = new B(new Lazy<A>(() => a));
Lazy<T>将代码的执行延迟到稍后,允许两个构造函数完成。
这是一个糟糕的解决方案 - 其他语言使这更容易 - 所以我会建议一种更实用的方法。
关于C# 设计问题 : two immutable objects with references to each other,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49304616/
为什么我的简单对象不使用 Immutable.fromJS({}) 转换为 Immutable.Map() 这是 Map() - 按预期工作 > var mymap = Immutable.Map({
如何在Immutable.js列表的任意位置插入元素? 最佳答案 您正在寻找 splice method: Splice returns a new indexed Iterable by repla
https://facebook.github.io/immutable-js/docs/#/is 我尝试比较 2 个 OrderedMap,但 Immutable.is 函数不起作用。 它只能比较
对于标准的 JS 对象,可以使用解构赋值,例如: let obj = {name: 'james', code: '007'} let {name, code} = obj // creates ne
如何获取 immutable.js 映射的第一个键(不是值)? 基本上myMap.first()将返回值,但我对 key 感兴趣...... 我可以先执行 forEach 并存储,但必须是更好的方法!
查看this ,我认为一成不变。 Record是表示“javascript不可变对象(immutable对象)”的数据结构,但我想一次更新多个字段,而不是每次创建多个调用set的对象。 我想做这样的事
为什么可以改变 scala.collection.immutable.SortedMap 和 scala.collection.immutable.TreeMap? scala> import sca
好的,我有一个对象列表,非常标准。 const list = Immutable.List([{type:'thang',data:{id:'pants'}}]); 现在我想把裤子换成短裤……所以我在
如何在 OrderedMap 的末尾添加项目? 我试过了 this.boxes = this.boxes.setIn(data); 感谢您的帮助 最佳答案 一种可能的方法是使用 concat
在开始使用 reactjs 和 redux 进行开发之后,我认为在使用 redux 的同时使用 immutable.js 会更好。 但是...也许我是智障,或者在正确使用它之前需要一些练习,一切都崩溃
我要在 Immutable.js 映射上进行一系列更改。 我应该在什么时候更喜欢使用 withMutations而不是创建中间的不可变映射? 来自 Immutable.js 文档: If you ne
我想使用 Immutable 的流类型定义来描述 map 的形状。 您可以通过以下方式描述物体的形状: const stateShape: { id: number, isActive: bo
这两个 NuGet 包有什么区别?如果我正在创建 .net 4.51 项目,我应该使用其中一个吗?我过去使用过 Microsoft.Bcl.Immutable 的测试版,但只是想知道其中一个是否会比另
基本上我想要做的是,如果您按下按钮,那么条目应该获得一个新的 CEntry。如果有人可以帮助我,那就太好了。谢谢! struct AView: View { var entries = [CEn
我有来自框架的协议(protocol) public protocol BaseMappable { /// This function is where all variable mappi
Swift 开发相对较新。尝试修改其他人编写的几个函数。目标是在用户登录后第一次调用此路径(该部分尚未设置)时离开原始路径,并在后续调用中使用其他路径。 因此,在编写将指向首次通过或非首次通过的逻辑之
这段代码 extension Collection { mutating func f() { removeFirst() } } 处理错误 cannot use mutating m
我正在处理一些使用许多不同项目“列表”的 NodeJS 代码。底层实现使用包括 Immutable.List、Immutable.Set、Javascript Array 和 Javascript S
我正在尝试使用 Reacts Immutability helpers 或 Immutable js 合并一个不可变的对象数组。我正在尝试创建一个仅包含名称已更改的记录的列表。如果名称在提交前已多次更
我被困在一个 Cannot use mutating member on immutable value: function call returns immutable value 这段代码错误:
我是一名优秀的程序员,十分优秀!