1

I have this code in c++ to do this but I want to do the same in C# but it's not working and I can't figure it out why?

    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;

}

this print "1 2 3 4 5 .... n" but in 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();
        }
    }

I tried in diferent ways but the only I get is:

Type 'n'
10
Printing to: 10
End

any idea in how to make it works? and why when creating the class numero it's not calling the numero constuctor??

Irvin Dominin
  • 30,819
  • 9
  • 77
  • 111
  • 5
    In C#, unlike C++, an array of `T[]` does *not* automatically call the/a default constructor for each T item automatically - instead the fields will be initialized to `null` when T is a reference type. (So the C++ approach, which is mostly a hack relying on side-effects won't work in C# :-) – user2864740 Feb 01 '14 at 00:21
  • @user2864740: fascinating! thank you. – Sam Axe Feb 01 '14 at 00:24
  • You can hide iteration in LINQ obviously like `Enumerable.Range(1,n).Select(i => {Console.WriteLine(i);return i;})` – Alexei Levenkov Feb 01 '14 at 00:51

1 Answers1

6

The C++ version works because you're allocating n many elements of Numero on the stack which causes the compiler to invoke Numero's constructor n times. Ultimately your program is still using a loop, but it's hidden within the generated machine code rather than explicitly delcared in your code.

The psuedocode of the machine-code generated by the compiler resembles this:

 numbers = Allocate( n * sizeof( Number ) );
 for(int i=0;i<n;i++) numbers[i].ctor();

This is not possible in pure C# because classes exist on the heap and require explicit constructor calls (which you'd have to do in a loop), and while structs exist on the stack (sort-of) they do not have their default constructor called when they're allocated (see this QA for an explanation: Why can't I define a default constructor for a struct in .NET? ).

Your question sounds like a bad brain-teaser question that tests one's familiarity with a language, but has zero practical use because the only way to implement a loop is with a jump instruction somewhere (be it a loop, recursive call, or explicit goto; there are no other ways to do this - the only way to hide it is by calling another method or compiler-feature that performs the prohibited instruction).

Note that you could pull this off with Array.Initialize which will call the default constructor of a value-type array's elements, but C# doesn't allow you to define such a default constructor (but the CLI does allow them to exist). This might be to allow for some Managed C++ / C++/CLR interop feature, however.

Community
  • 1
  • 1
Dai
  • 141,631
  • 28
  • 261
  • 374