带有约束的结构

时间:2009-07-31 20:39:28

标签: c# constructor struct

我很难弄清楚如何在C#中编写一个 struct ,它对字段的值有约束。例如, System.DateTime

DateTime d = new DateTime();

将值 01/01/0001 12:00:00 AM 置于 d 中。但是我不能写一个显式的无参数构造函数,因为 struct 不允许有一个显式的无参数构造函数。那么,我如何创建一个 struct ,它将在我想要的约束中默认构建?

我唯一能想到的是设计属性,使它们在我想要的约束内返回值。例如,如果我存储一个我希望大于0的 int ,我只需在返回值中添加一个并禁止设置为小于1.这是明智的路线吗?

7 个答案:

答案 0 :(得分:3)

有关其他信息,请参阅this问题的答案。基本上,没有参数,值类型字段总是初始化为默认值作为性能优化,因为值类型通常在数组等中使用更大的数字。

如果您想要 true 约束,则应考虑创建一个类,但如果在使用您的类时性能有问题,则可以采用“智能属性”。对于DateTime类型,是的,它执行“智能”属性,将日期存储为根据请求转换为特定格式的数字(通过属性访问)。 01/01/0001 12:00:00 AM 实际上是设计默认内部0的表示。

答案 1 :(得分:2)

我认为你最好建议在那种情况下使用课程。将此结构放入其中,在无参数构造函数中,您可以显式设置希望结构包含的值。

答案 2 :(得分:1)

需要值类型语义吗?一个普通的不可变类有什么问题?

答案 3 :(得分:0)

我建议使用Reflector来确切地检查DateTime结构的编写方式。这应该为您提供所需的洞察力。

答案 4 :(得分:0)

CLR中的部分值类型语义是值类型始终具有合理的有效默认值(此外,使用常规初始化规则,该合理的默认值由默认初始化值类型表示)。如果您的类型不是这种情况,那么它不应该是struct

答案 5 :(得分:0)

DateTime将其默认值设置为DateTime.Min。当你打印出来时(按照其ToString()方法),打印出当前值,就是这样。

以下是一个例子:

class Program
{
    static void Main(string[] args)
    {
        ChrisTime t = new ChrisTime();
        Console.WriteLine(t);

        DateTime time = new DateTime();
        Console.WriteLine(time);

        Console.Read();
    }
}

public struct ChrisTime
{
    private int _length;

    public int Length
    {
        get
        {
            return _length;
        }
        set
        {
            _length = value;
        }
    }

    public override string ToString()
    {
        return Length.ToString();
    }

}

打印出来:

  

0
  01/01/0001 00:00:00

但是如果你尝试将_length初始化为1,它将会失败,因为你不能这样做,也不会设置构造函数。但是DateTime的ToString方法执行:

public override string ToString()
{
    return DateTimeFormat.Format(this, null, DateTimeFormatInfo.CurrentInfo);
}

您看到DateTime的字段格式化为字符串格式。所以日,月,年,小时,分钟,秒都为零,正如您对新构造的对象所期望的那样。

答案 6 :(得分:0)

DateTime结构对其值有约束,因为所有值设置都是通过方法调用完成的。请注意DateTime上的所有属性都是只读的。

所以...

public struct BetweenNegativeFiveAndFive
{
    public static readonly int MinValue;
    public static readonly int MaxValue;
    int _value;
    public int Value
    {
        get { return _value; }
    }
    public int Add(int a)
    {
        int b = _value + a;
        if (b >= MinValue && b <= MaxValue)
            _value = b;
        return _value;
    }
    static Foo()
    {
        MinValue = -5;
        MaxValue = 5;
    }
}