在. net中,值类型(c# struct)不能有不带形参的构造函数。根据这篇文章,这是CLI规范要求的。实际情况是,对于每一个值类型,都会创建一个默认构造函数(由编译器创建?),该构造函数将所有成员初始化为零(或null)。

为什么不允许定义这样的默认构造函数?

一个简单的应用是有理数:

public struct Rational {
    private long numerator;
    private long denominator;

    public Rational(long num, long denom)
    { /* Todo: Find GCD etc. */ }

    public Rational(long num)
    {
        numerator = num;
        denominator = 1;
    }

    public Rational() // This is not allowed
    {
        numerator = 0;
        denominator = 1;
    }
}

使用当前版本的c#,默认的Rational是0/0,这不是很酷。

在c# 4.0中,默认参数会帮助解决这个问题吗?还是会调用clr定义的默认构造函数?


琼恩·斯基特回答说:

用你的例子来说,如果有人这么做了,你希望发生什么: Rational[]分数= new Rational[1000]; 它应该遍历构造函数1000次吗?

当然应该,这就是为什么我首先写默认构造函数的原因。当没有明确定义默认构造函数时,CLR应该使用默认的归零构造函数;这样你只需要为你所使用的付费。然后,如果我想要一个包含1000个非默认Rational的容器(并且想要优化掉这1000个结构),我将使用List<Rational>而不是数组。

在我看来,这个原因还不足以阻止定义默认构造函数。


当前回答

短的说明:

在c++中,结构体和类只是一枚硬币的两面。唯一真正的区别是,一个默认是公开的,另一个是私有的。

在. net中,结构体和类之间有更大的区别。主要是struct提供值类型语义,而class提供引用类型语义。当您开始考虑此更改的含义时,其他更改也开始变得更有意义,包括您描述的构造函数行为。

其他回答

struct是一种值类型,值类型在声明后必须具有默认值。

MyClass m;
MyStruct m2;

如果您像上面那样声明了两个字段而没有实例化它们,那么就会中断调试器,m将为null,而m2则不是。鉴于此,无参数构造函数将没有意义,事实上,结构上的所有构造函数都是赋值,只是声明了它本身就已经存在了。实际上,m2可以在上面的例子中非常愉快地使用,并调用它的方法(如果有的话),并操纵它的字段和属性!

我找到了一个简单的解决方法:

struct Data
    {
        public int Point { get; set; }
        public HazardMap Map { get; set; }
        public Data Initialize()
        {
            Point = 1; //set anything you want as default
            Map = new HazardMap();
            return this;
        }
    }

在代码中只需执行:

Data input = new Data().Initialize();

短的说明:

在c++中,结构体和类只是一枚硬币的两面。唯一真正的区别是,一个默认是公开的,另一个是私有的。

在. net中,结构体和类之间有更大的区别。主要是struct提供值类型语义,而class提供引用类型语义。当您开始考虑此更改的含义时,其他更改也开始变得更有意义,包括您描述的构造函数行为。

我使用的是空合并操作符(??)与支持字段的组合,就像这样:

public struct SomeStruct {
  private SomeRefType m_MyRefVariableBackingField;

  public SomeRefType MyRefVariable {
    get { return m_MyRefVariableBackingField ?? (m_MyRefVariableBackingField = new SomeRefType()); }
  }
}

希望这对你有所帮助;)

注意:空合并赋值目前是c# 8.0的一个特性提议。

因为使用的是c#,所以不能定义默认构造函数。

在. net中,结构可以有默认构造函数,尽管我不知道有任何特定的语言支持它。