I\'m trying to make default value for my struct. For example default value for Int - 0, for DateTime - 1/1/0001 12:00:00 AM. As known we can\'t define parameterless constru
You can't. Structures are always pre-zeroed, and there is no guarantee the constructor is ever called (e.g. new MyStruct[10]
). If you need default values other than zero, you need to use a class. That's why you can't change the default constructor in the first place (until C# 6) - it never executes.
The closest you can get is by using Nullable
fields, and interpreting them to have some default value if they are null through a property:
public struct MyStruct
{
int? myInt;
public int MyInt { get { return myInt ?? 42; } set { myInt = value; } }
}
myInt
is still pre-zeroed, but you interpret the "zero" as your own default value (in this case, 42). Of course, this may be entirely unnecessary overhead :)
As for the Console.WriteLine
, it simply calls the virtual ToString
. You can change it to return it whatever you want.
Your problem is not with the behaviour of C#/.Net. The way you instantiate the struct effectively creates an instance with default values for all member fields.
The Console.WriteLine
converts its argument to a string using the ToString() method. The default implementation (Object.ToString()
) simply writes the fully qualified class name (namespace and name, as you call it).
If you want another visualisation, you should override the ToString
method:
public struct Test
{
int num;
string str;
public override string ToString()
{
return $"num: {num} - str: {str}";
}
}
Printing out objects of the C# results with namespaces unless you override .ToString() for your objects. Can you define your struct like below and try it ?
public struct Test
{
int num;
string str;
public override string ToString()
{
return "Some string representation of this struct";
}
}
PS: default(Test) gives you a struct contains default(int) and default(string) which I mean Test.num is 0
and Test.str is null
Hope this helps
You can also do this:
public struct MyStruct
{
public static readonly Default = new MyStruct(42);
public int i;
public MyStruct(int i)
{
this.i = i;
}
}
And then when you create a default struct of this type do this:
public MyStruct newStruct = MyStruct.Default;
But of course, this won't override default and other programmers will bump their heads a few times. Really consider if a struct is the way to go, from the microsoft docs:
"A structure type (or struct type) is a value type that can encapsulate data and related functionality. Typically, you use structure types to design small data-centric types that provide little or no behavior."
Consider this: if you had 2 values in your struct and you wanted to make constructors, would 2 or less constructors suffice? If the answer is no, then the answer is: don't use a struct.
What you probably want to do is to override ToString()
, e.g.
struct Test
{
int num;
string str;
public override string ToString ()
{
return string.Format ($"{str} | {num}");
}
}
As you have mentioned, it is impossible to define default values for fields other than default values for their appropriate types. However, with an overriden ToString()
, you will see better formatted information about your structure in the console and during debugging.