如何在C#中为结构创建默认值?

时间:2016-10-04 07:37:06

标签: c# struct

我试图为我的结构制作默认值。 例如,Int - 0的默认值,对于DateTime - 1/1/0001 12:00:00 AM。 众所周知,我们无法在结构中定义无参数构造函数。

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

如何为struct创建默认值?

6 个答案:

答案 0 :(得分:17)

你做不到。结构总是预先归零,并且无法保证构造函数被调用(例如new MyStruct[10])。如果您需要零以外的默认值,则需要使用类。这就是为什么你不能在第一时间改变默认构造函数(直到C#6) - 它永远不会执行。

最接近的是使用Nullable字段,如果它们在属性中为null,则将它们解释为具有某些默认值:

public struct MyStruct
{
  int? myInt;

  public int MyInt { get { return myInt ?? 42; } set { myInt = value; } }
}

myInt仍然预先归零,但您将“零”解释为您自己的默认值(在本例中为42)。当然,这可能是完全不必要的开销:)

对于Console.WriteLine,它只是调用虚拟ToString。您可以将其更改为随意返回。

答案 1 :(得分:2)

你的问题不在于C#/ .Net的行为。实例化struct的方法有效地创建了一个具有所有成员字段的默认值的实例。

Console.WriteLine使用ToString()方法将其参数转换为字符串。默认实现(Object.ToString())只是编写完全限定的类名(命名空间和名称,如您所说)。

如果您想要其他可视化,则应覆盖ToString方法:

public struct Test
{
    int num;
    string str;
    public override string ToString()
    {
        return $"num: {num} - str: {str}";
    } 
}

答案 2 :(得分:1)

使用命名空间打印出C#结果的对象,除非您为对象覆盖.ToString()。您可以像下面一样定义结构并尝试吗?

public struct Test
{
    int num;
    string str;
    public override string ToString()
    {
        return "Some string representation of this struct";
    }
}

PS:default(Test)给你一个包含default(int)和default(string)的结构,我的意思是Test.num是0而Test.str是null

希望这有帮助

答案 3 :(得分:0)

您可能想要做的是覆盖ToString(),例如

struct Test
{
    int num;
    string str;

    public override string ToString ()
    {
        return string.Format ($"{str} | {num}");
    }
}

正如您所提到的,无法为其相应类型的默认值以外的字段定义默认值。但是,使用覆盖ToString(),您将在控制台和调试期间看到有关结构的更好格式化信息。

答案 4 :(得分:0)

这是我的看法,以防有人觉得它有用。

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

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

我的结构中有一个静态方法,所以我可以这样做:

var data = MyStruct.Null;

代替

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

或者创建一个自定义构造函数来传递数据。

答案 5 :(得分:-3)

您也可以这样做:

public struct MyStruct
{
    public static readonly Default = new MyStruct(42);

    public int i;

    public MyStruct(int i)
    {
        this.i = i;
    }
}

然后在创建此类型的默认结构时执行以下操作:

public MyStruct newStruct = MyStruct.Default;

但是,当然,这不会覆盖默认值,其他程序员会碰几次头。真正考虑从microsoft docs出发的结构是否可行:

“结构类型(或结构类型)是可以封装数据和相关功能的值类型。通常,您可以使用结构类型来设计较小的以数据为中心行为很少或根本没有行为的类型。”

考虑一下:如果您的结构中有2个值,并且想要构造一个构造函数,那么2个或更少的构造函数就足够了吗?如果答案是否定的,那么答案是:不要使用结构。