如何在没有设置器的情况下设置私有变量值?

Posted

技术标签:

【中文标题】如何在没有设置器的情况下设置私有变量值?【英文标题】:How to set a private variable value without a setter? 【发布时间】:2021-10-27 19:31:00 【问题描述】:

我目前正在执行单元测试任务。 在项目中,我有一个银行帐户类和一个单元测试类。 在 BankAccount 类中,我们有一个变量 private double balance get;

使用私有类型的变量并且只获取,例如通过提取现金的类函数完成后如何更新余额。

public double Debit (double amount)
        /*Ensuring Debit Amount is Valid and Balance Available for Transaction*/
        
            IsAmountVerified(amount);     
            if (IsAmountVerified(amount) is false)  throw new ArgumentOutOfRangeException("",WRONG_AMOUNT); 
            if (balance < amount)  throw new ArgumentOutOfRangeException("",INSUFFICIENT_BALANCE); 
            else **balance -= amount**;
        /*Return Value*/
            return amount;
        

如何更新余额?还要将此变量设为私有,我无法在 UnitTesting 类中访问它。

 [TestMethod]
        public void DepositTest1()
        
            BankAccount Account = new BankAccount(100, "Baldip Singh");
            Account.Deposit(1);
            Assert.AreEqual(101, Account.balance);
        

感谢您的任何见解,干杯。

【问题讨论】:

你不能写入只读属性,傻。您可能可以写入其支持字段,假设它有一个(并非所有属性都这样做......例如,如果余额是其他东西的总和怎么办?)为此,您必须对被测系统进行逆向工程. 没错!我得出的结论是,这可能是写作业时的错误-_- 如果你想在构造函数之外改变它,你需要将set;添加到属性中。 Within the BankAccount class we have a variable 你有一个属性 @Baldeep 的重要说明 - double 完全不适合货币金额;如果您不想与财务人员进行尴尬的对话,请改用decimal 【参考方案1】:

为了支持这种特定场景,许多工具(序列化程序等)使用的一个技巧是查找名为&lt;propertyName&gt;k__BackingField 的字段的已知自动属性模式,例如:

[CompilerGenerated]
private readonly double <balance>k__BackingField;

您可以通过反射访问它(Type 上的GetField(...),指定一个包含非公共和实例的BindingFlags,然后是SetValue(...))。但是,这不适用于手动实现的支持字段,或与支持字段没有 1:1 关系的属性,例如:

private double balance => 42;

不过,一般来说,我会说:使用您实际获得的 API 表面。如果给定的 API 不能满足您的需求:更改/扩展 API,而不是颠覆它。例如,您可以添加一个 setter:

// note I've changed the type, name, and accessibility here!
public decimal Balance  get; private set; 

(您也可以查看init 而不是set

【讨论】:

【参考方案2】:

仅获取自动实现的属性是不可变的(构造函数内除外)。要声明一个返回私有字段变量值的 get-only 属性,请使用:

private double _balance;
private double balance => _balance;

【讨论】:

balance 不如Balance 不变性是个谎言(除非您在 ROM 或专门的强化系统上执行)——可访问性也是如此。如果你足够努力,没有什么是真正不可变或不可访问的:)【参考方案3】:

如果您的业务场景需要更新余额,您需要为该属性添加私有 setter(以防只允许在您的类内更新),否则您的业务场景将无法正常工作。

如果您想从私有字段中获取值,您可以添加公共 getter-properties 或返回所需值的公共方法。

在您的情况下,我建议您像这样更改您的逻辑: 公共双平衡get;私有集;

【讨论】:

以上是关于如何在没有设置器的情况下设置私有变量值?的主要内容,如果未能解决你的问题,请参考以下文章

如何知道为 union 设置了哪个变量值?

如何在 swiftui 中为子视图设置私有状态变量?

如何恢复环境变量的默认设置

如何设置PATH环境变量

如何在 gitlab-ci.yml 文件中通过 ssh 设置变量值

平台内置业务表变量值设置