使用new运算符创建类的实例时,将在堆上分配内存.当您使用new运算符创建结构的实例时,在堆上还是堆栈上分配内存?
在.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;
}
}
Run Code Online (Sandbox Code Playgroud)
使用当前版本的C#,默认的Rational 0/0并不是那么酷.
PS:默认参数是否有助于解决C#4.0或者是否会调用CLR定义的默认构造函数?
Jon Skeet回答道:
要使用您的示例,当有人执行时您希望发生什么:
Run Code Online (Sandbox Code Playgroud)Rational[] fractions = new Rational[1000];它应该通过你的构造函数1000次?
当然应该,这就是我首先编写默认构造函数的原因.当没有定义显式默认构造函数时,CLR应该使用默认的归零构造函数; 这样你只需支付你使用的费用.然后,如果我想要一个1000个非默认Rational的容器(并希望优化1000个结构),我将使用一个 …
public struct Test
{
public double Val;
public Test(double val = double.NaN) { Val = val; }
public bool IsValid { get { return !double.IsNaN(Val); } }
}
Test myTest = new Test();
bool valid = myTest.IsValid;
Run Code Online (Sandbox Code Playgroud)
上面给出了valid==true因为没有调用默认arg的构造函数,并且使用标准默认值val = 0.0创建了对象.
如果结构是一个类,那么行为就是valid==false我所期望的.
我发现这种行为上的差异,特别是结构案例中的行为令人惊讶和不直观 - 发生了什么?stuct构造的默认arg服务是什么? 如果它无用为什么要让这个编译?
更新:澄清这里的重点不在于行为是什么 - 而是为什么在没有警告的情况下进行编译并且行为不直观.即如果没有应用默认的arg,因为在新的Test()情况下没有调用构造函数,那么为什么要让它编译?
继这个关于在Visual Studio 2015中使用不同Visual Basic版本的问题之后,我将在Visual Basic 14中运行新的语言功能,如此处和此处所述.
其中之一是能够在结构中使用无参数构造函数,如下所示:
Structure MyStruct1
Public f As Integer
Sub New()
f = 15
End Sub
End Structure
Run Code Online (Sandbox Code Playgroud)
当我在Visual Studio 2015中的代码中尝试此操作时,我仍然会在以下情况下出现红色错误波形New():
BC30629结构不能声明没有参数的非共享"Sub New".
我还没有看到任何说明在发布之前被拉掉的地方.
我误解了这个新功能的作用吗?