Hi All
I'm not sure if there is a forum for Newbies, so I'm going to post this here and if there is a FAQ on this and a newbie section then please let me know.
I hope you can help a newbie to C# programming with something that I am struggling regarding constructor chaining.
If I have multiple fields of the same type that I want to be populated on instaniation is there a way to indicate which field want to be populated in the chained call.
For example I have a class that has 2 private properties/variable:
class ClassName
{
// Field data.
private int id;
private int age;
// Chained constructors
ClassName() : this(0) {}
ClassName(int myID) : this(myID, 0) { }
ClassName(int myAge) : this(0, myAge) { }
// Master constructor
ClassName(int myID, int myAge)
{
id = myID;
age = myAge;
}
}
Main would look like this say:
public static void Main()
{
// Is this argumentfor ID or Age as they are both of type int?
ClassName myClass = new class(10);
}
I hope you can see what my problem is? Is there a way to allocate values to exact constructor arguments or is this an issue with constructor chaining that has to be lived with, and I should ignore chaining when dealing with constructors that contain arguments with this same type?
Many thanks
Gary
Loading
VulpesPosted Jun 13, 2012, 7:21 PM
So, you'll have to delete one of the constructors which takes one argument in order that the application can compile.
This, of course, means that only one of the fields can be initialized with the value passed to this constructor. As a result of constructor chaining the other argument will be zero.
If you want to initialize both fields with non-zero values, then you should call the constructor which takes both arguments directly i.e. no chaining is necessary.
You'll also need to make the constructors public (they're private by default) so they can be accessed by code outside the class.
The following compiles and runs OK:
using System;
class ClassName
{
// Field data.
public int id;
public int age;
// Chained constructors
public ClassName() : this(0) {}
public ClassName(int myID) : this(myID, 0) { }
// Master constructor
public ClassName(int myID, int myAge)
{
id = myID;
age = myAge;
}
}
class Test
{
public static void Main()
{
ClassName myClass = new ClassName(10);
Console.WriteLine(myClass.id); // 10
Console.WriteLine(myClass.age); // 0
ClassName myClass2 = new ClassName(11, 20);
Console.WriteLine(myClass2.id); // 11
Console.WriteLine(myClass2.age); // 20
Console.ReadKey();
}
}
Incidentally, the default value for an int field is 0 anyway so the other field will be initialized to 0 here without the need for constructor chaining.
VulpesPosted Jun 19, 2012, 5:25 AM
You can then have a public static 'factory' method for creating the single instance (if it hasn't been created already) which calls the private constructor internally.
GaryPosted Jun 19, 2012, 5:11 AM
Must admit I am tryint to think of a time when having a private defaulted constructor wouold be useful, and there are many in C++, but not so much in C#.
Anyhow.
Thanks for helping.
VulpesPosted Jun 18, 2012, 2:16 PM
GaryPosted Jun 18, 2012, 1:46 PM
Sorry, another constructor question
I know that C# provides the concept of static classes, but is it possible to achive similar by declaring the default construtor as private, with no other public constructors? I seem to remeber somthing similar in C++.
VulpesPosted Jun 14, 2012, 4:09 AM
As you say, the combination of named and optional arguments greatly reduce the need for constructor chaining.
It's a pity that these weren't introduced in C# 1.0 (they've always been in VB.NET) but it was argued at the time that optional arguments were bad because the default value of the argument had to be 'baked into' the method signature. If the default value were subsequently changed, then any code which called that method had to be recompiled.
In the end the C# team had to relent on this because they were trying to improve Office and COM interop which had always been a pain from C# because of the copious use of optional arguments in COM methods.
The problem now is that everybody's got used to the previous way of working and so you don't see optional and named arguments used much outside of interop code.
GaryPosted Jun 13, 2012, 7:46 PM
This concept does now change my view on constructor chaining and if it is now really needed, as you can have a single constructor and simply name the values you want to be set at instansiation. Although, as you say, that is only available in .NET/C# 4.0(+).
What do you think regarding design, is constructor chaining really needed in anything 4.0 onwards?
GaryPosted Jun 13, 2012, 7:35 PM
GaryPosted Jun 13, 2012, 7:31 PM
VulpesPosted Jun 13, 2012, 7:29 PM
Please check out this link for details:
http://msdn.microsoft.com/en-us/library/dd264739.aspx
GaryPosted Jun 13, 2012, 7:26 PM
I thought that would be the case, just wanted to be sure.
I wonder if in future iterations of the language, or the .NET platform, named argument passing will be implemented, as is available with Oracles PL/SQL...it would make life so much easier.
Thanks for the help though.