unsafePtr
unsafePtr

Reputation: 1773

How to make a default value for the struct in C#?

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 constructor in structure.

struct Test
{
    int num;
    string str;
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(default(Test)); // shows namespace and name of struct test.Test
        Console.WriteLine(new Test()); // same

        Console.ReadKey(true);
    }
}

How can I make a default value for struct?

Upvotes: 46

Views: 83409

Answers (6)

Darkgaze
Darkgaze

Reputation: 2573

This is my take on this in case somebody finds it useful.

public struct MyStruct
{
    public int item1;
    public float item2;
    public float item3;

    public static MyStruct Null => new MyStruct(-1, 0, 0);
}

I have a static method inside my struct so that I can do this:

var data = MyStruct.Null;

instead of

var data = new MyStruct();
data.item1 = -1;
...

Or create a custom constructor to pass the data.

Upvotes: 3

CaseyHofland
CaseyHofland

Reputation: 538

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.

Upvotes: 1

jeroenh
jeroenh

Reputation: 26792

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

Upvotes: 6

Andrew Sklyarevsky
Andrew Sklyarevsky

Reputation: 2135

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.

Upvotes: 0

Luaan
Luaan

Reputation: 63772

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.

Upvotes: 58

Cihan Uygun
Cihan Uygun

Reputation: 2138

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

Upvotes: 1

Related Questions