无法在我的班级中将类型“字符串”转换为“字符串[]”

时间:2019-01-10 14:40:44

标签: c#

尝试获取工人等级时遇到一些问题。

我有Class Worker,我想在控制台中显示worker等级,但是我遇到了麻烦。

namespace GYA.HW4.OOP.Classes.Classes {
    class Worker {
        public string[] Ranks { get; set; }

        public int CapacityOfDetails { get; set; }
        public Worker() {
            this.Ranks = new string[3] { "Не опытный", "Опытный", "Мастер" };
        }
        public string[] GetRanks() {
            return this.Ranks;
        }
    }
}

我要显示它的班级:

namespace GYA.HW4.OOP.Classes.Classes {
    class ProcessBuilding {
        public bool BuildUnit(Worker[] workers, Unit unit) {
            for (int i = 0; i < workers.Length; i++) {
                unit.Details += workers[i].CapacityOfDetails;//type
            }
            if (unit.Details == unit.CountOfDetailsForDone) {
                unit.StatusDone = true;
            } else {
                unit.StatusDone = false;
            }
            return unit.StatusDone;
        }
        public Worker[] AssignWorkers(int countOfWorkers) {
            Random randomizer = new Random();
            Worker[] workers = new Worker[countOfWorkers];
            for (int i = 0; i < workers.Length; i++) {   
                int randomNumber = randomizer.Next(0, 2);
                workers[i] = new Worker();
                workers[i].Ranks = workers[i].GetRanks()[randomNumber]; <= (Troubles is here)
                if (randomNumber == 0 ) {
                    workers[i].CapacityOfDetails = 1;
                }else if(randomNumber == 1) {
                    workers[i].CapacityOfDetails = 3;
                } else if (randomNumber == 2) {
                    workers[i].CapacityOfDetails = 5;
                }
                Console.WriteLine($"Рабочий с рангом {workers[i].Ranks} установил {workers[i].CapacityOfDetails} детал(ь/и)");
            }
            return workers;
        }     
    }
}

我该怎么做? 对不起,我只是在学习

4 个答案:

答案 0 :(得分:1)

公开实现的内部细节(例如您使用的集合的类型)可能是一个问题–您的用户将依赖您使用数组。他们可以直接操纵集合的内容。

您确实应该将实现与接口分开:

class Worker {
  private List<string> theRanks = new List<string>();

  public ICollection<string> Ranks {
    get {
      return new ReadOnlyCollection<string>(theRanks);
    }
  }

  public void AddRank(string newRank) {
    theRanks.Add(newRank);
  }
}

通过使用我可以轻松添加到的集合,我解决了添加问题。 Array是固定长度的,添加到长度中意味着复制(并且破坏了客户在直接暴露时可能获取的所有引用)。

所以你

workers[i].Ranks = workers[i].GetRanks()[randomNumber];

成为

works[i].AddRank(workers[i].Ranks[randomNumber]);

答案 1 :(得分:1)

这看起来像是班级设计问题。您的Worker类有一个Ranks字段,该字段显然用于两个不同的事物。首先,将所有可能的等级存储在那里。然后,稍后您尝试将其用于特定的Worker实例的等级。

作为附带的语言注释,“Неопытный”不适合上下文,应为“Неопытный”,因为这是主题的持久属性。

要解决您的问题,您需要将概念分开。像这样:

namespace GYA.HW4.OOP.Classes.Classes 
{
    public class Worker 
    {
        public static readonly string[] AllRanks => new [] { "Неопытный", "Опытный", "Мастер" };

        public string Rank { get; internal set; }
    }
}

然后您可以像使用它一样

workers[i].Rank = Worker.AllRanks[randomNumber]; // (No troubles here anymore)

然后

Console.WriteLine($"A {workers[i].Rank} worker installed {workers[i].CapacityOfDetails} tool(s)");

答案 2 :(得分:0)

在线

workers[i].Ranks = workers[i].GetRanks()[randomNumber];

...部分workers[i].Ranks是一个字符串数组。

呼叫workers[i].GetRanks()[randomNumber]时,您会得到一个字符串。 您不能将单个字符串放在需要数组的位置。

答案 3 :(得分:0)

错误说明:

workers[i].Ranks = workers[i].GetRanks()[randomNumber]

Ranks被定义为字符串数组。

GetRanks()返回一个字符串数组。

GetRanks()[randomNumber]将返回一个字符串。无法将其分配给Ranks

“快速而肮脏的”解决方案

也许您想创建一个仅包含一个字符串的新数组?

在这种情况下,您可以创建一个新数组:

workers[i].Ranks = new string[] { workers[i].GetRanks()[randomNumber] };

但是

正如其他人指出的那样,总的来说,这不是操作数组的推荐方法,您可能会在类之外公开和处理太多细节(字符串arrray)。更糟糕的是,主要的混乱是由于您试图将Ranks用于两个不同的目的(存储所有可能的值并存储实际选择的随机值)

在严格阅读程序的同时,如果只需要在控制台上打印值,那么我至少要避免从类外部操纵Rank东西。当前,这违反了OOP encapsulation principleseparation of concerns

在我看来,您想在创建工人时为其分配随机等级。 那么,可能等级的预定义列表不应是实例变量,而应该是静态变量。

您可以在Worker对象上使用一种方法来选择可能的等级,并为其他字段分配正确的值:

经过审查的代码,改进了关注点和封装的分离:

class Worker {
    private static string[] AvailableRanks = new string[3] { "Не опытный", "Опытный", "Мастер" };

    public string Rank { get; private set; }
    public int CapacityOfDetails { get; private set; }

    public Worker() {
    }

    public AssignRandomRank(Random randomizer) {
        int randomNumber = randomizer.Next(0, 2);
        this.Rank = AvailableRanks[randomNumber];
        if (randomNumber == 0 ) {
            CapacityOfDetails = 1;
        } else if(randomNumber == 1) {
            CapacityOfDetails = 3;
        } else if (randomNumber == 2) {
            CapacityOfDetails = 5;
        }
    }
}

在另一类中:

    // the only concern of this method is creating the workers, initialize them and do a console log of the work.
    // The worker class itself *knows* how to initialize itself.
    // much more clearer, in my opinion 

    public Worker[] AssignWorkers(int countOfWorkers) {
        Worker[] workers = new Worker[countOfWorkers];
        Random randomizer = new Random();
        for (int i = 0; i < workers.Length; i++) {  
            workers[i] = new Worker();
            workers[i].AssignRandomRank(randomizer);

            Console.WriteLine($"Рабочий с рангом {workers[i].Ranks} установил {workers[i].CapacityOfDetails} детал(ь/и)");
        }
        return workers;
    }     

请注意,仍然存在更好的重构/改进的空间。

但是,这可能更适合[codereview.se]。