C#构造函数传入不同参数实例化对象返回重复属性值问题求助
问题原因
- 第一:
OriginModel中定义了静态字段_CharacterOrigin,静态字段属于类全局共享,所有实例都会共用同一个值,每次实例化新对象时都会覆盖这个全局值。 - 第二:C#的实例字段初始化器(也就是你声明
_OriginStartingLevels时直接赋值的那行代码)执行时机早于构造函数。也就是说你在构造函数里给_CharacterOrigin赋值之前,_OriginStartingLevels就已经完成了初始化,用的是赋值前的旧_CharacterOrigin值。
两次实例化的实际执行顺序如下:
- 第一次实例化
Milquetoast类型的OriginModel:- 先执行
_OriginStartingLevels初始化,此时静态_CharacterOrigin还未赋值,默认是枚举的0值也就是Milquetoast,所以属性初始化正确为11 - 执行构造函数,把静态
_CharacterOrigin设为Milquetoast
- 先执行
- 第二次实例化
Lone Survivor类型的OriginModel:- 先执行
_OriginStartingLevels初始化,此时静态_CharacterOrigin还是上一步的Milquetoast,所以初始化出来的属性还是11 - 执行构造函数,才把静态
_CharacterOrigin改成Lone Survivor,但此时属性已经初始化完成,不会再更新
- 先执行
这就是Lone Survivor实例的vitality值不符合预期的原因,添加更多实例时,每个实例的属性都会用前一个实例设置的静态_CharacterOrigin值初始化,所以会出现前几个属性重复的情况。
修复方案
- 删掉无用的静态字段
public static OriginType _CharacterOrigin;,不需要这个全局共享字段 - 把
_OriginStartingLevels的初始化放到构造函数里执行,用当前实例的出身类型传参,修改后的代码参考:
using BloodBorneTableTopGame.Models.PlayerStatsModel; namespace BloodBorneTableTopGame.Models.OriginModels { public class OriginModel { // 删掉了静态_CharacterOrigin字段 public OriginModel(OriginType origin) { CharacterOrigin = origin; // 构造函数内再初始化属性,用当前实例的出身类型 _OriginStartingLevels = new PlayerStatModel(origin); } public enum OriginType { Milquetoast, LoneSurvivor, TroubledChildhood, ViolentPast, Professional, MilitaryVeteran, NobleScion, CruelFate, WasteOfSkin } public OriginType CharacterOrigin; public string OriginName { get { return GetName(CharacterOrigin); } } public string OriginDescription { get { return Description(CharacterOrigin); } } public string Description(OriginType origin) => origin switch { OriginType.Milquetoast => "Ordinary, happy upbringing. All attributes average.", OriginType.LoneSurvivor => "Lone survivor of lost hamlet. High life essence and vigor.", OriginType.TroubledChildhood => "Suffered misfortune in youth. Highly resilient as a result.", OriginType.ViolentPast => "Terribly violent past. Rash, but stronger for it.", OriginType.Professional => "Born specialist, fit for sleuthing or academia.", OriginType.MilitaryVeteran => "Experienced in war. A soldier with strength and skill.", OriginType.NobleScion => "Scion to a respectable line with faith in your pedigree.", OriginType.CruelFate => "Faced terrible hardships, but now confident in your purpose.", OriginType.WasteOfSkin => "You are nothing. Talentless. You shouldn't have been born.", _ => "Error: No Origin Type Selected" }; public string GetName(OriginType origin) => origin switch { OriginType.Milquetoast => "Milquetoast", OriginType.LoneSurvivor => "Lone Survivor", OriginType.TroubledChildhood => "Troubled Childhood", OriginType.ViolentPast => "Violent Past", OriginType.Professional => "Professional", OriginType.MilitaryVeteran => "Military Veteran", OriginType.NobleScion => "Noble Scion", OriginType.CruelFate => "Cruel Fate", OriginType.WasteOfSkin => "Waste of Skin", _ => "Error: No Origin Type Selected" }; // 声明时不再初始化 private PlayerStatModel _OriginStartingLevels; public PlayerStatModel OriginStartingLevels { get => _OriginStartingLevels; } } }
内容的提问来源于stack exchange,提问作者dsmith1515
相关产品推荐
相关产品推荐

