如何使用 DateTime.Now.Year 作为可选参数的默认值

How can I use DateTime.Now.Year as default for optional parameters

你能告诉我如何解决这个错误吗

Default parameter value must be a compile-time constant"

我知道这个问题并且已经在 Stack Overflow 上看到了方法的解决方案,但是我不知道如何解决这个问题 类。

public class member
{
    public string name { get; }
    public string email { get; set; }
    public int entryYear;
    static int memberNbr;

    public member (string _name, int _entryyear = DateTime.Now.Year, string _email = "")
    {
        name = _name;
        entryyear = _entryyear;
        email = _email;
    }
}

你可以使用第二个构造函数..

public class member
            {
                public string name { get; }
                public string email { get; set; }
                public int entryYear = DateTime.Now.Year;
                static int memberNbr;

                public member(string _name, string _email = "")
                {
                    name = _name;
                    email = _email;
                }                
                public member(string _name, int _entryyear , string _email = "")
                {
                    name = _name;
                    entryYear = _entryyear;
                    email = _email;
                }
            }

与其将其作为可选参数,不如使用不同的构造函数重载呢?在第二个构造函数中,不要将 entryYear 作为参数,而是在构造函数体内对其进行初始化?

并且在我们这样做的同时,让我们使用适当的 C# 约定,例如 属性 名称是 PascalCase 和构造函数参数是 camelCased。并且不使用 属性 名称的缩写,并且当 MemberNumber 明显属于单个实例时不要将其设为静态。

public class Member
{
    public string Name { get; }

    public string Email { get; }

    public int EntryYear { get; }

    public int MemberNumber {get; }

    public Member(string name, int entryYear, string email = "")
    {
        Mame = Name;
        EntryYear = entryYear;
        Email = email;
    }

    public Member(string name, string email = "")
    {
        Mame = Name;
        EntryYear = DateTime.Now.Year;
        Email = email;
    }
}

你没有问过,但用空字符串初始化电子邮件确实没有意义。将它默认为 null 可能更好。

鉴于不可能将非常量值作为默认参数,您将不得不使用重载:

public class Member
{
    public string Name { get; }
    public string Email { get; set; }
    public int EntryYear { get; set; }

    private int _memberNumber;

    public Member(string name) : this(name, DateTime.Now.Year, "")
    { }

    public Member(string name, int year) : this(name, year, "")
    { }

    public Member(string name, string email) : this(name, DateTime.Now.Year, email)
    { }

    public Member(string name, int entryYear, string email)
    {
        Name = name;
        EntryYear = entryYear;
        Email = email;
    }
}

注意我已经为你修复了大小写,你应该尽早学习c#约定。此外,_memberNumber 不应该是静态的,除非所有成员都有相同的数字,这有点奇怪。

关于 MemberNumber,您可能需要这样的基本信息:

public static class MemberHelpers
{
    // you would have to load this if the data is persisted in some way
    private static int _lastMemberNumber;

    public static int GetNewMemberNumber()
    {
        return _lastMemberNumber++;
    }
}

public Member(string name, int entryYear, string email)
{
    Name = name;
    EntryYear = entryYear;
    Email = email;

    _memberNumber = MemberHelpers.GetNewMemberNumber();
}

一年不能是明智的,例如。 int.MinValue。因此理论上您可以将默认参数设置为 int.MinValue,并将其解释为 DateTime.Now.Year.

但是,代码应该始终针对阅读进行优化,这绝对不会使发生的事情一目了然。所以我绝对不建议在 public API 中这样做。在私有方法中虽然没问题,但请确保记录下发生的事情。

如果您在测试中使用 int.MinValue 等极端情况,这也可能导致测试出现问题。

因此,我肯定会选择一个可为 null 的 int,并使用默认参数 null 来表示 DateTime.Now.Year。

即便如此,我仍然会在 public API 中建议不要这样做,而是改用方法重载。然而,对于非 public 代码,通过减少方法和使用默认参数可以更好地减少混乱。