我很难弄清楚如何在C#中编写一个 struct ,它对字段的值有约束。例如, System.DateTime
DateTime d = new DateTime();
将值 01/01/0001 12:00:00 AM 置于 d 中。但是我不能写一个显式的无参数构造函数,因为 struct 不允许有一个显式的无参数构造函数。那么,我如何创建一个 struct ,它将在我想要的约束中默认构建?
我唯一能想到的是设计属性,使它们在我想要的约束内返回值。例如,如果我存储一个我希望大于0的 int ,我只需在返回值中添加一个并禁止设置为小于1.这是明智的路线吗?
答案 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;
}
}