viKK
viKK

Reputation: 15

Constructor Confusion - 'never assigned to, and will always have its default value'

These are my instructions:

iii) Give Pair a constructor.
iv) Give Pair a set property, for key.
v) Also provide a get property for key.

After having checked out as many constructor threads I could find on this forum for information, I found that although the answers given were very accurate and precise, there's still something I don't fully understand.

We were told that if a constructor is defined at all then all the attributes must be initialised as well as that piece-meal intialisation of attributes in a struct is forbidden.

My code:

 using System ;
   using System.Drawing ; 
   // above namespace 
   // has the class Color 

   public class PairApp
   {
      public static void Main()
      {
            Pair two = new Pair();
            two.print(); 
      }

      struct Pair
      {

                int key;
                Color colour;


                public void print()
                {
                    Console.WriteLine("key : " + key );
                    Console.WriteLine("colour : " + colour);
                }
      }
   }
   //
   // Some values from the 
   // class Color
   //    Color.Red
   //    Color.Cyan
   //    Color.DarkGray
   //

My questions:

  1. Why would I need to create a constructor for Pair? Isn't that what Pair two = new Pair(); does?

  2. If Pair two = new Pair(); is the constructor, then it has been defined, right? If it has been defined, how would I go about not getting the errors listed below.

  3. What does my lecturer mean when he states that 'piece-meal initialisation of attributes in a struct is forbidden'? I often struggle with the terminology used within the programming world so help me out :)

Debug:

airapp.cs(17,16): warning CS0649: Field `PairApp.Pair.key' is never assigned to, and will always have its default value `0'
pairapp.cs(18,18): warning CS0649: Field `PairApp.Pair.colour' is never assigned to, and will always have its default value
Compilation succeeded - 2 warning(s)

EDIT UPDATED CODE:

Now it runs with none of the errors it had before. A massive thanks to everyone for explaining it so well!

However, it puts forth the following error: pairapp.cs(14,14): error CS1520: Class, struct, or interface method must have a return type. After looking it up I don't see how it's any different to the example shown at: http://msdn.microsoft.com/en-us/library/aa288208(v=vs.71).aspx

What I'm trying to accomplish (hope I've not managed to confuse myself) is to create a constructor that assigns the values to the fields of the struct. Have I done this correctly?

I have also removed the below section as it felt superfluous after having added what can be seen in the updated version further below.

Pair two;

        two = new Pair();
        two.print();

My updated code:

using System ;
   using System.Drawing ; 
   // above namespace 
   // has the class Color 

   public class PairApp
   {
      public static void Main()
      {

            Lion p1 = new Lion(5, Color.Red);
            p1.print(); 
      }
      public Lion(int key, Color colour)
      {
            this.key = key;
            this.colour = colour;
      } 
      struct Pair
      {

                int key;
                Color colour;


                public void print()
                {
                    Console.WriteLine("key : " + key );
                    Console.WriteLine("colour : " + colour);
                }
      }
   }
   //
   // Some values from the 
   // class Color
   //    Color.Red
   //    Color.Cyan
   //    Color.DarkGray
   //

Upvotes: 0

Views: 681

Answers (2)

BoltClock
BoltClock

Reputation: 723398

  1. You don't need to create a constructor for Pair because it will work just fine with its default constructor (the example that you've listed). But if your struct has fields that should be initialized with certain values, it's a good idea to create a constructor that takes those values and constructs your struct for you right away. The default constructor will not initialize your fields for you with anything other than their default values (as shown in your error output).

    Which brings us to your next question...

  2. A type can in fact have one or more constructors. The one you've listed is the default constructor, which is created automatically if you don't write any of your own and takes no parameters and does nothing aside from allowing an instance of your struct to be created in memory.

    In your case, you'll want to make a constructor that takes two parameters, key and colour, and assigns them to the fields in your struct. The signature should look like public Pair(int key, Color colour), and you'll need to assign the fields this.key and this.colour to those parameters in your constructor.

  3. Piecemeal initialization in this case probably just refers to initializing only some of the fields and not all of them (that word doesn't have any programming-specific meaning that I know of).

    The warnings that you see are precisely the consequence of leaving certain fields uninitialized or unassigned in code. As another example, if you made a constructor that only assigned a value to key, but never to colour, what would the output be?


There are two problems with your constructor:

  1. It needs to be the same name as the type it is constructing. So in this case, it's Pair. (Turns out there was a typo in my answer which might have misled you, I've fixed that now.)

  2. It needs to appear inside the struct definition, not alongside it. (In other words, alongside the fields and methods within the struct itself.)

Upvotes: 2

Sinatr
Sinatr

Reputation: 21969

Pair two = new Pair();

is not a constructor, it's assigning instance of Pair to local variable. Instance is created by using constructor, but it's not defined here.

Constructor is a thing, defined inside your class. It looks like a method without return value and can have overrides with parameters (to ease your life).

struct Pair
{
    public Pair() {} // constructor
}

This sounds wrong or you rephrase it to be wrong:

if a constructor is defined at all then all the attributes must be initialised as well as that piece-meal intialisation of attributes in a struct is forbidden

Your issue is access modifiers. By default your fields are private (if I remember right in C++ struct has by default public fields, this is probably the reason of confusion). Because you don't define any constructor - default is used (which is only allocates memory for all fields, but is not assigning any value to them).

Private fields and no field initialization in constructor (actually, no constructor defined) in the struct - means you are not assigning anything to it at all (you are only using values in print method). This makes compiler sure, what you are mistaken somewhere. Adding any sort of settings will make compiler shut =D

struct Pair
{
    int key;
    Color colour;

    public void print()
    {
        Console.WriteLine("key : " + key );
        Console.WriteLine("colour : " + colour);
    }

    // no more warning, but.. are you sure? 
    public void LOL()
    {
        key = 0;
        Color = Color.Red;
    }
}   

Upvotes: 0

Related Questions