// record struct 自动提供按值判等;显式构造函数负责建立合法值publicreadonlyrecordstructMoney{publicdecimalAmount{get;}publicstringCurrency{get;}publicMoney(decimalamount,stringcurrency){if(amount<0)thrownewDomainException("金额不能为负");if(string.IsNullOrWhiteSpace(currency))thrownewDomainException("必须指定币种");Amount=amount;Currency=currency.ToUpperInvariant();}publicMoneyAdd(Moneyother){if(Currency!=other.Currency)thrownewDomainException("币种不同,不能相加");returnnewMoney(Amount+other.Amount,Currency);}publicMoneySubtract(Moneyother){if(Currency!=other.Currency||other.Amount>Amount)thrownewDomainException("币种不同或余额不足");returnnewMoney(Amount-other.Amount,Currency);}publicMoneyMultiply(inttimes){if(times<0)thrownewDomainException("倍数不能为负");returnnewMoney(Amount*times,Currency);}}// 用法:// var price = new Money(99m, "CNY");// var total = price.Multiply(3); // 新对象,price 不变// price == new Money(99m, "CNY") // true(按值判等)
// 实体基类:提供 ID 与按 ID 判等publicabstractclassEntity<TId>whereTId:notnull{publicTIdId{get;protectedset;}=default!;publicoverrideboolEquals(object?obj)=>objisEntity<TId>other&&EqualityComparer<TId>.Default.Equals(Id,other.Id);publicoverrideintGetHashCode()=>Id.GetHashCode();}// 实体:有身份、有状态流转publicclassCustomer:Entity<CustomerId>{publicCustomerNameName{get;privateset;}// 用值对象装字段publicEmailEmail{get;privateset;}// 用值对象publicCustomerStatusStatus{get;privateset;}privatereadonlyList<Address>_addresses=new();// 值对象集合publicIReadOnlyCollection<Address>Addresses=>_addresses.AsReadOnly();publicCustomer(CustomerIdid,CustomerNamename,Emailemail):base(){Id=id;Name=name??thrownewDomainException("姓名必填");Email=email??thrownewDomainException("邮箱必填");Status=CustomerStatus.Active;}publicvoidChangeEmail(EmailnewEmail){if(Status==CustomerStatus.Closed)thrownewDomainException("已注销客户不能改邮箱");Email=newEmail;}}