简体   繁体   English

具有依赖属性的 C# 类

[英]C# Class with dependent properties

I'm very new to C# programming, and I'm currently struggling with what should be (I think) a piece of cake code for experienced programmers.我对 C# 编程很陌生,我目前正在努力解决什么应该是(我认为)经验丰富的程序员的小菜一碟代码。 I want to write a very little app to calculate a tax (21%) on a number:我想编写一个很小的应用程序来计算一个数字的税收(21%):

  • If I define an exclVAT number, it should return the calculated inclVAT number如果我定义了一个 exclVAT 号,它应该返回计算出的 inclVAT 号
  • If I define an inclVAT number, it should return the calculated exclVAT number如果我定义了一个 inclVAT 号,它应该返回计算出的 exclVAT 号

My goal is to have something like this: an app that gives the results as soon as you type a value in one of the two boxes:我的目标是有这样的东西:一个应用程序,只要你在两个框中输入一个值就会给出结果:

VAT utility (This will be done in WPF using XAML, with an INotifyPropertyChanged interface, but this is not the goal of my question). VAT 实用程序(这将在 WPF 中使用 XAML 完成,带有 INotifyPropertyChanged 接口,但这不是我的问题的目标)。

I'm trying to do this with 1 class, and 2 properties: inclVat and exclVat (both as type double).我正在尝试使用 1 个类和 2 个属性来执行此操作:inclVat 和 exclVat(均为 double 类型)。 But the tricky thing is that both properties depend on each other.但棘手的是这两个属性相互依赖。 So if I set/change the exclVat property to 100, I want to have the inclVat property to be changed to 121. And if I set/change the inclVat value to 100, I want the exclVat property changed to 0,83.因此,如果我将 exclVat 属性设置/更改为 100,我希望将 inclVat 属性更改为 121。如果我将 inclVat 值设置/更改为 100,我希望将 exclVat 属性更改为 0,83。

I already come up with this code, but is is not sufficient, as the public property fields don't change when I change the values on them...我已经想出了这段代码,但这还不够,因为当我更改它们的值时,公共属性字段不会改变......

The Class:班上:

public class Vat
    {

        private double _inclVat;

        public double InclVat
        {
            get 
            {
                if (_ExclVat == 0)
                {
                    return _inclVat;
                }
                else
                {
                    return (_ExclVat * 1.21);
                }
                
            }
            set
            {
                _inclVat = value;
            }
        }

        private double _ExclVat;

        public double ExclVat
        {
            get 
            {
                    return System.Math.Round(_inclVat / 1.21, 2);
            }
            set
            {
                _ExclVat = value;
                
            }
        }
    }

And when I run it with some assignments:当我用一些作业运行它时:

Vat Number = new Vat();
Number.InclVat = 100;

System.Console.WriteLine($"InclVat: {Number.InclVat}");
System.Console.WriteLine($"ExclVat: {Number.ExclVat}");

System.Console.WriteLine("Changing inclVat to 200");
Number.InclVat = 200;

System.Console.WriteLine($"InclVat: {Number.InclVat}");
System.Console.WriteLine($"ExclVat: {Number.ExclVat}");

System.Console.WriteLine("Changing exclVat to 100");
Number.ExclVat = 100;

System.Console.WriteLine($"InclVat: {Number.InclVat}");
System.Console.WriteLine($"ExclVat: {Number.ExclVat}");

I have the following output:我有以下输出:

InclVat: 100
ExclVat: 82,64
Changing inclVat to 200
InclVat: 200
ExclVat: 165,29
Changing exclVat to 100
InclVat: 121
ExclVat: 165,29

In the beginning it's ok, but as soon as I change the exclVat property, the output isn't ok anymore (last 2 lines).一开始还可以,但是一旦我更改了 exclVat 属性,输出就不再正常了(最后 2 行)。 Can anyone help me with this?谁能帮我这个?

You can put something like this:你可以这样写:

  public class Vat {
    private decimal m_IncludeVat; // <- decimal is a better choice for finance

    // To compute VAT we should know the percent; let it be known
    public const decimal Percent = 18.0m;

    public decimal IncludeVat {
      get => m_IncludeVat;
      set {
        // negative cash are usually invalid; if it's not the case, drop this check
        if (value < 0)
          throw new ArgumentOutOfRangeException(nameof(value));

        m_IncludeVat = value;
        Tax = Math.Round(m_IncludeVat / 100 * Percent, 2);
      }   
    }

    public decimal ExcludeVat {
      get => m_IncludeVat - Tax;
      set {
        if (value < 0)
          throw new ArgumentOutOfRangeException(nameof(value));

        m_IncludeVat = Math.Round(value / (100 - Percent) * 100, 2);
        Tax = m_IncludeVat - value; 
      }   
    }

    // Let's be nice and provide Tax value as well as IncludeVat, ExcludeVat 
    public decimal Tax {get; private set;}

    public override string ToString() =>
      $"Include: {IncludeVat:f2}; exclude: {ExcludeVat:f2} (tax: {Tax:f2})";
  }

Let's add some tests:让我们添加一些测试:

  (decimal cash, bool isInclude)[] tests = new (decimal cash, bool isInclude)[] {
    (100, true),
    (200, true),
    (100, false),
    (121.95m, true)  
  };

  var report = string.Join(Environment.NewLine, tests
    .Select(test => {
      Vat num = new Vat();

      if (test.isInclude)
        num.IncludeVat = test.cash;
      else
        num.ExcludeVat = test.cash;

      return num;
    }));

  Console.WriteLine(report);

Outcome:结果:

Include: 100,00; exclude: 82,00 (tax: 18,00)
Include: 200,00; exclude: 164,00 (tax: 36,00)
Include: 121,95; exclude: 100,00 (tax: 21,95)
Include: 121,95; exclude: 100,00 (tax: 21,95)

it seems like you want the computed value of InclVat [the public property], not the backing field _inclVat when you are getting ExclVat .好像你想要的计算值InclVat [公益属性],不支持字段_inclVat当你正在ExclVat Try changing ExclVal 's get to尝试将ExclValget更改为

 return System.Math.Round(InclVat / 1.21, 2);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM