制作与其结构实例交互的方法

Making methods that interact with instances of their structs

我们在 class 了解了结构,我们的任务是在结构中创建一个方法,该方法与另一个实例相比会更改实例的字段。例如,如果对方是经理,则更改姓名。

struct Employee 
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName
    {
        get => FirstName + LastName;
    }
    public int Age { get; set; }
    public string Role { get; set; }
    public double Salary { get; set; }
    public bool IsManager { get; set; }

    public static void EditInfo(ref Employee e1, ref Employee e2)
    {
        if (e1.IsManager)
        {
            Console.WriteLine($"Feel free to set {e2.FirstName}'s info: ");
            e2.FirstName = Console.ReadLine();
            e2.LastName = Console.ReadLine();
            Console.WriteLine($"From now on thy name is {e2.FullName}!");
        }
        else if (e2.IsManager)
        {
            Console.WriteLine($"Feel free to set {e1.FirstName}'s info: ");
            e1.FirstName = Console.ReadLine();
            e1.LastName = Console.ReadLine();
            Console.WriteLine($"From now on thy name is {e1.FullName}!");
        }
    }
}

现在,我有一种直觉,我的创作很糟糕。我完全不确定如何实际处理这个问题,这看起来像是对实际业务应用程序学习的宝贵一课。我将不胜感激使这些方法更好地与结构的多个实例交互所必需的每一个提示和技巧。

编辑: 澄清

首先,您应该使可变属性 private set;、构造函数接受初始状态,并使 EditInfo 成为实例方法。这或多或少将每个 Employee 视为具有访问控制的数据库记录,从而创建更简单的关系。

public class Employee
{
    public Employee(string firstName, string lastName, bool isManager, ...)
    {
        FirstName = firstName;
        LastName = lastName;
        IsManager = isManager;
        // remaining properties...
    }

    public string FirstName { get; private set; }
    public string LastName { get; private set; }
    public bool IsManager { get; private set; }
    // remaining properties...

    public void Edit(Employee requester)
    {
        if (requester.IsManager) {
            // query input from the user, make changes, and notify the user.
        } else {
            // notify the user that he doesn't have permission to edit this employee. 
        }
    }
}

这样使用它就变成了:

var manager = new Employee("Your", "Boss", isManager: true);
var sheep = new Employee("John", "Doe", isManager: false);

sheep.Edit(manager); // Essentially says "edit sheep using manager as permission".

其次,除非您的导师禁止您使用 class,否则您应该将其设为 class 并删除所有 ref 声明。 structref 在适当的情况下非常有用,但除非您意识到权衡和严格的代码,否则很容易引入一个错误,考虑到您的经验水平很难推理.

类 不会自动复制或需要 ref 关键字。另一方面,结构确实会在没有 ref 的情况下进行复制,因此在对其进行修改的每个调用站点上语义上都要求(但不强制执行)它。这具有您可能不知道的其他含义。考虑属性。属性不能用 ref 传递,只能传递局部变量、字段和数组元素。不幸的是,这意味着目前无法通过 ref 传递结构 属性(尽管在未来的 C# 版本中可能会发生变化)。这可能会在路上咬你。

总而言之,在 C# 中更喜欢 classes 除非你有充分的理由使用结构(即 GC 性能,非常特殊用途的类型)。最重要的是,以可读性为目标。