Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you specify what a default state of a derived struct should be in C#?

Tags:

c#

.net

struct

I've seen different questions on SO about not being able to use parameterless constructors or not setting field initializers, but I think my question kind of goes a step beyond that.

What I would like to know is, how would I go about setting up the "default" value of a struct I need to define? Say I'm making a TaxID struct, and the default value needs to be 999-99-9999 for whatever reason. This is already done with other structs in .NET, namely the DateTime. Any time you declare a DateTime the value is immediately set to Jan 1 0001 12:00 AM. Why does it get set to this value and not 0/0/0000 00:00:0000 AM? There must be something going on behind the scenes that makes the value actually make "sense" at it's "default", even given the restrictions put on us by c# with regards to structs.

like image 867
Joseph Avatar asked Apr 07 '09 18:04

Joseph


People also ask

Can you set default values in struct C?

Default values MAY be defined on struct members. Defaults appear at the end of a field definition with a C-like = {value} pattern.

What is default struct?

5, the default value of a struct consists of the value that results from setting all value type fields to their default value and all reference type fields to null .

When deriving a struct from a class struct default access specifiers for base class struct are public?

(B) Members of a class are private by default and members of struct are public by default. When deriving a struct from a class/struct, default access-specifier for a base class/struct is public and when deriving a class, default access specifier is private.

What is the default constructor of a struct?

A default constructor is a constructor which can be called with no arguments (either defined with an empty parameter list, or with default arguments provided for every parameter). A type with a public default constructor is DefaultConstructible.


1 Answers

In general, this should be avoided. If you need to require a good, default case which would require construction, you should consider changing to a class.

One of the core design guidelines for structs is: Do ensure that a state where all instance data is set to zero, false, or null (as appropriate) is valid.

For details, see the design guidelines.


I just looked this section up in the design guidelines 2nd edition, and they have an example in detail there using properties and non-conventional overrides to work around this, as well. The basic concept was to save the value privately in a way that 0 is the "good default", and do some form of transform in every property and method override (including ToString). In their case, they used a positive integer as an example, and always save curVal-1 in the private member, so the default value (0) is treated like a value of 1. They added a constructor with an int val, and save value-1 internally, etc.

This seems like a lot of hidden, unexpected overhead, though - so I'd personally still recommend (and use) a class in this case.

--- Edit in response to comments ---

DateTime, as your example, is the way it is because 0 == 1/1/0001 at Midnight. DateTime uses a single, ulong to represent ticks from 1/1/0001. That is why (from here):

"The DateTime value type represents dates and times with values ranging from 12:00:00 midnight, January 1, 0001 Anno Domini (Common Era) through 11:59:59 P.M., December 31, 9999 A.D. (C.E.) "

This is the full range of ulong in ticks. A "0" in the struct of DateTime is treated as 1/1/0001 when you convert to a string - the values aren't 1 + 1 + .... - it's a single 0.

like image 70
Reed Copsey Avatar answered Oct 12 '22 01:10

Reed Copsey