我在c ++中使用此代码来执行此操作,但我想在C#中执行相同的操作,但它无法正常工作,我无法弄明白为什么?
class Numero
{
public:
static int num;
Numero()
{
cout<<num++<<" ";
}
};
int Numero::num=1;
int main()
{
int n;
cout<<"Type n: ";
cin>>n;
Numero obj[n];
return 0;
}
此印刷品“1 2 3 4 5 .... n” 但在C#
class numero
{
public static int num {get; set;}
public numero()
{
Console.WriteLine(num);
num++;
}
}
class Program
{
static void Main(string[] args)
{
numero.num=1;
Console.WriteLine("Type 'n'");
int n = int.Parse( Console.ReadLine());
Console.WriteLine("Printing to: {0}", n);
numero[] num_1 = new numero[n];
Console.WriteLine("End");
Console.ReadLine();
}
}
我尝试过不同的方式,但唯一得到的是:
Type 'n' 10 Printing to: 10 End
有关如何使其有效的任何想法?以及为什么在创建类numero时它不会调用numero constuctor ??
答案 0 :(得分:6)
C ++版本的工作原理是因为您在堆栈上分配n
许多Numero
元素,导致编译器调用Numero
的构造函数n
次。最终,您的程序仍在使用循环,但它隐藏在生成的机器代码中,而不是在代码中明确显示。
编译器生成的机器代码的伪代码类似于:
numbers = Allocate( n * sizeof( Number ) );
for(int i=0;i<n;i++) numbers[i].ctor();
这在纯C#中是不可能的,因为类存在于堆上并且需要显式构造函数调用(您必须在循环中执行),并且堆栈中存在结构({ {3}})他们在分配时没有调用默认构造函数(请参阅此QA以获得解释:sort-of)。
你的问题听起来像一个糟糕的脑筋急转弯问题,测试一个人对语言的熟悉程度,但没有实际用途,因为实现循环的唯一方法是使用跳转指令某处(无论如何)循环,递归调用或显式goto;没有其他方法可以做到这一点 - 隐藏它的唯一方法是调用另一个执行禁止指令的方法或编译器功能。
请注意,可以将Array.Initialize
拉出来,它将调用值类型数组元素的默认构造函数,但C#不允许您定义这样的默认构造函数(但CLI确实允许它们存在)。但这可能是为了允许某些托管C ++ / C ++ / CLR互操作功能。