使用舒适的代码为结构上的数组赋值

本文关键字:结构上 数组 赋值 代码 舒适 | 更新日期: 2023-09-27 18:29:59

这个想法很简单。为商店的"Departments"创建一个结构,为其提供一个用于命名的变量(一个名为"Department"的字符串),以及一个用于保存在该部门中完成的所有购买的数组。

现在,我希望每次我在特定部门购买时,它都会根据部门名称和购买金额自动应用折扣。

现在,示例类:

class Program
{
    struct Departments
    {
        public string Department;
        private double[] _buys;
        public double[] Buys
        {
            get { return _buys; }
            set
            {
                if (value > 100)
                {
                    if (Department == "CLOTH")
                    _buys = value * .95;
                    if (Department == "FOOD")
                    _buys = value * .90;
                    if (Department == "OTHER")
                    _buys = value * .97;
                }
                _buys = value;
            }
        }
    }
    static void Main()
    {
        var departments = new Departments[3];
        departments[0].Department = "CLOTH";
        departments[1].Department = "FOOD";
        departments[2].Department = "OTHER";
        departments[0].Buys = new double[5];
        departments[0].Buys[0] = 105;
    }
}

注意行departments[0].Buys[0] = 105,这是我想要保存购买的东西的方式,"代码简单"。。。

现在,请注意结构的属性Buys,它是一个"数组属性"。然后,当我使用value > 100条件时,它给出了一个明显的错误,不能从double转换为double[]

问题。。。我如何为value > 100写一个正确的条件,还必须在结构上加什么才能实现这一点?

我尝试过使用"Indexers",但只要我尝试过,我就无法通过departments[0].Buys[0] = 105以正确的方式接收assignets。

请注意,我想保留这个模式,特别是为了方便简单地说departments[0].Buys[0] = 105到一次购买

编辑:

上一个结构体"Departments"仅用于示例目的。我不会回答如何通过另一种方式获得正确的"Departments",我想知道如何使集合参数在数组的各个元素上工作

使用舒适的代码为结构上的数组赋值

另一个潜在的解决方案是为_buys数组创建另一个类:

class Buys
{
    private double[] _buys;
    public Buys (int capacity)
    {
        _buys = new double[capacity];
    }
    public double this[int index]
    {
        get { return _buys; }
        set 
        {
            if (value > 100)
            {
                if (Department == "CLOTH")
                    value = value * .95;
                if (Department == "FOOD")
                    value = value * .90;
                if (Department == "OTHER")
                    value = value * .97;
            }
            _buys = value;
        }
    }
}
struct Departments
{
    public string Department;
    public Buys Buys;
}
static void Main()
{
    var departments = new Departments[3];
    departments[0].Department = "CLOTH";
    departments[1].Department = "FOOD";
    departments[2].Department = "OTHER";
    departments[0].Buys = new Buys(5);
    departments[0].Buys[0] = 105;
}

您最好使用List<double>来记录购买情况。这样列表就可以动态增长。您还可以使用索引来获取列表元素。

您可以使用字典简化折扣代码。

对于这些数据,最好使用class,而不是structStruct通常更好地用于不可变值。使类代表单个部门,并在其中存储适当的折扣。

这样的东西:

class Program
{
    class Department
    {
        public string Name;
        public double Discount;
        private List<double> _buys = new List<double>();
        public List<double> Buys
        {
            get { return _buys; }
        }
        public void AddBuy(double value)
        {
            _buys.Add(value > 100 ? value * discount : value);
        }
    }
    static void Main()
    {
        var departments = new List<Department>();
        departments.Add(new Department { Name = "CLOTH", Discount = 0.95 });
        departments.Add(new Department { Name = "FOOD", Discount = 0.90 });
        departments.Add(new Department { Name = "OTHER", Discount = 0.97 });
        departments[0].AddBuy(105);
        Console.WriteLine(departments[0].Buys[0]);
    }
}

我还有很多其他方法可以改进这个设计,但这应该会让你继续前进。

您可以执行类似的操作

public class Departments
{
    public string Department;
    public MyList buys;
    public Departments()
    {
        buys = new MyList(this, 5);
    }
}
public class MyList
{
    private double[] backingList;
    private Departments owner;
    public MyList(Departments owner, int size)
    {
        this.owner = owner;
        backingList = new T[size];
    }
    public double this[int index]
    {
        get{ return backingList[index]; }
        set { backingList[index] = discountFor(owner.Department) * value; }
    }
    private float discountFor(string department)
    {
        switch(department)
        {
        case "department1":
            return 0.5f;
        //...
        default:
             return 1.0f;
        }
    }
}

然而,你并没有通过把折扣放在设置者自己身上来保持良好的关注点分离。更好的代码看起来像

departments[0].Buys[0] = DiscountFor("department1") * 105;

由于您的错误,您可以执行这样的操作。

struct Departments
    {
        public string Department;
        private double[] _buys;
        public double[] Buys
        {
            get { return _buys; }
            set
            {
                for (int i = 0; i < value.Length; i++)
                {
                    if (value[i] > 100)
                    {
                        if (Department == "CLOTH")
                            _buys[i] = value[i] * .95; if (Department == "FOOD")
                            _buys[i] = value[i] * .90; if (Department == "OTHER")
                            _buys[i] = value[i] * .97;
                    }
                }
                _buys = value;
            }
        }
    }

您可以创建一个方法来进行如下设置:

        public double[] Buys { get; set; }
        public void SetBuy(int index, double value)
        {
           if (value > 100)
           {
              if (Department == "CLOTH")
               value = value * .95;
              if (Department == "FOOD")
               value = value * .90;
              if (Department == "OTHER")
               value = value * .97;
           }
           _buys[index] = value;
        }

包含对可变项的可变引用的结构通常是个坏主意,因为这样的结构最终会显示出值和引用语义的奇怪组合。例如,的效果应该是什么

dep1、dep2部门;。。。dep1=dep2;dep1.Department="CLOTH";dep1.Buys[5]=123;

很难说这样的声明会或应该影响dep2.Buys[5]。如果给定结构的Buys字段/属性总是引用同一个数组,那么这种语义可能是可以容忍的,但如果需要调整数组的大小,会发生什么?