GOTCHA 4 You can t force calls to your value-type constructors


GOTCHA #4 You can't force calls to your value-type constructors

Among other differences between reference types and value types, one of the most surprising is that you are not allowed to define your own no-parameter constructor (one that takes no parameter) for a value type. If you try, you get the following error:

 error CS0568: Structs cannot contain explicit parameterless constructors. 

C# and VB.NET provide a no-parameter constructor and won't let you write an alternate implementation.

The consequence of this is that you have no control over how your value-type object is created by a user. For instance, in the case of a reference type (class), you can dictate what parameters are necessary to create an object by writing different constructors. The compiler makes sure that a user calls one of these constructors when creating the object. In the case of a value type, you can't define a no-parameter constructor. So you can't force developers to enter some specific values before using a value type. They can create an instance of your value type with no parameters. Take a look at Example 1-6.

Example 1-6. Example of using no-parameter constructor of value type

C# (ValueTypeConstructor)

 //MyType.cs using System; namespace ValueTypeInstantiation {     public struct MyType     {         private int val;         public override string ToString()         {             return "The value is " + val;         }          //public MyType() {} // Can't be provided          public MyType(int initialValue)         {             val = initialValue;         }     } } using System; namespace ValueTypeInstantiation {     class Test     {         [STAThread]         static void Main(string[] args)         {             MyType instance1 = new MyType(10);             Console.WriteLine("instance1: " + instance1);             MyType instance2 = new MyType();             Console.WriteLine("instance2: " + instance2);         }     } } 

VB.NET (ValueTypeConstructor)

 'MyType.vb Public Structure MyType     Private val As Integer     Public Overrides Function ToString() As String         Return "The value is " & val     End Function     'Public Sub New() ' Can't be provided     'End Sub      Public Sub New(ByVal initialValue As Integer)         val = initialValue     End Sub End Structure 'Test.vb Public Class Test     Public Shared Sub Main()             Dim instance1 as new MyType(10)             Console.WriteLine("instance1: " & instance1)             Dim instance2  as new M y Type             Console.WriteLine("instance2: " & instance2)     End Sub End Class 

Note that the value type MyType has one constructor which takes an integer. However, in Main of the Test class you are able to create an instance of MyType not only using the constructor provided, but also using the no-parameter constructor. What if you want to enforce a rule that MyType.val must be set to the value given in the constructor or to a value of, say, 10? Unfortunately that is not possible. Each field of a value type is initialized to its default value. For instance, int/Integer fields will be initialized to 0 and bool/Boolean types to false. The output from Example 1-6 is shown in Figure 1-5.

Figure 1-5. Output from Example 1-6


IN A NUTSHELL

Be aware that for value types, no matter how many constructors you write, you are not allowed to write your own no-parameter constructor. A user of your type may create an object using the no-parameter constructor and there is no guarantee that any of the constructors you write is ever used.

SEE ALSO

Gotcha #2, "struct and class differ in behavior," Gotcha #3, "Returning value types from a method/property is risky," and Gotcha #9, "Typeless ArrayList isn't type-safe."



    .NET Gotachas
    .NET Gotachas
    ISBN: N/A
    EAN: N/A
    Year: 2005
    Pages: 126

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net