【问题标题】:How can I use DateTime.Now.Year as default for optional parameters如何使用 DateTime.Now.Year 作为可选参数的默认值
【发布时间】:2018-12-01 18:26:25
【问题描述】:

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

默认参数值必须是编译时常量"

我知道这个问题,并且已经在 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;
    }
}

【问题讨论】:

  • 您可以将其设为int?,默认为null,然后如果它以null 出现,则将该字段设置为您想要的非常数。
  • 如果您真的必须这样做,请将您的方法签名设为public member (string _name, int _entryyear = default(int), string _email = "") - _entryyear 将默认为default(int)(即0),然后在方法里面你可以做entryYear = _entryyear == default(int) ? DateTime.Now.Year : _entryyear;。提供的答案是解决此问题的一种更简洁的方法。
  • 感谢您的解决方案,但我在计算机科学研究的第一学期,不允许使用 int?
  • 你真的不能用int?。这听起来像是一种非常奇怪的教学方法!如果你这样做会怎样?
  • 刚才还不是讲座的题目,同学们改正了这个习题,看不懂,扣分。

标签: c# class optional-parameters


【解决方案1】:

不是让它成为一个可选参数,而是一个不同的构造函数重载呢?而在第二个构造函数中,不要将entryYear作为参数,而是在构造函数体中初始化它?

在此过程中,让我们使用适当的 C# 约定,例如属性名称为 PascalCase,构造函数参数为驼峰式。并且不要对属性名称使用缩写,并且当 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 可能会更好。

【讨论】:

  • 谢谢,这是一个我很容易理解的舒适解决方案。我将 memberNbr 设为静态,因为稍后它应该为每个对象增加一个。还没有实现。
  • @D.Brown 重点是为每个用户分配一个唯一的 MemberNumber?通过将其设为静态,它们将共享相同的 MemberNumber。
  • 是的,现在我明白了,但是您如何为每个成员分配一个唯一编号?当我使用静态时,每个人都会得到成员总数的数字(即 8 有 8 个成员,evreyone 得到数字 8)。当它不是静态的时候,每个人都会得到数字 1。
  • @D.Brown 您需要单独跟踪号码。如果使用 SQL Server 存储数据,它可以自动分配序号。
  • 没有 SQL,但我现在得到了解决方案。我只需要一个静态计数器和一个 ID,这不是静态的。非常感谢!
【解决方案2】:

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

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();
}

【讨论】:

  • 谢谢。顺便说一句,我将 memberNbr 设为静态,因为稍后它应该为每个对象增加一个。还没有实现。
【解决方案3】:

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

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;
                }
            }

【讨论】:

  • 通常在重载构造函数时,您只需调用另一个构造函数,其值类似于public member(string _name, string _email = "") : this(_name, DateTime.Now.Year, _email)
  • @juharr:小问题。您不会重载构造函数,而是创建多个构造函数。
  • @Flydog57 有趣的是,其他两个答案也称其为超载。
  • 因此是“小问题”。阅读docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…“类和结构体也可以定义多个构造函数,都不需要定义默认构造函数。”
【解决方案4】:

一年不可能是明智的,例如。整数最小值。所以理论上你可以将默认参数设置为 int.MinValue,并将其解释为 DateTime.Now.Year。

但是,代码应该始终针对阅读进行优化,而这绝对不能说明发生了什么。所以我绝对不建议在公共 API 中这样做。在私有方法中虽然可以,但请确保记录正在发生的事情。

如果您在测试中使用诸如 int.MinValue 之类的边缘情况,这也可能导致测试出现问题。

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

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

【讨论】:

    猜你喜欢
    • 2019-05-19
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多