Problems assigning const fields in a class to an initial value 
Author Message
 Problems assigning const fields in a class to an initial value

I am an experienced C++ developer and am embarking of my first project to
make serious use of C#.
Generaly the transition so far has been smooth, just a change of mindset (
e.g. I can't overide operator= anymore :-) ).

I have run into an issue with const fields on a class though.

e.g.

class Class1
{
    private int xVal;
    private int yVal;

    public Class1(int xVal, int yVal)
    {
        this.xVal = xVal;
        this.yVal = yVal;
    }

Quote:
}

class Class2
{
    private const Class1 veryAnnoying;

    public Class2()
    {
    }

Quote:
}

Now clearly this doesn't compile as Class1 needs to be initialised to
something.

OK

class Class2
{
    private const Class1 veryAnnoying = 0;

    public Class2()
    {
    }

Quote:
}

Clearly doesn't work either as the compiler cannot assign 0 to my class, so
I add an implicit
casting operator to Class1 to cast from int to Class1.

class Class1
{
    private int xVal;
    private int yVal;

    public Class1(int xVal, int yVal)
    {
        this.xVal = xVal;
        this.yVal = yVal;
    }

    public static implicit operator Class1(int val)
    {
        return new Class1(val, val);
    }

Quote:
}

Now the compiler complains that the value, 0, that I am assigning to the
private field is not const, er yes it is!

class Class2
{
    private const Class1 veryAnnoying = 0;

    public Class2()
    {
    }

Quote:
}

Now if I change the modifier from const to readonly then it compiles, but my
understanding is that readonly's only
difference to const it that it lets you initialise the the class field in
your constructor.  A const or readonly member
initialised in the way I am doing does not initialise in my constructor they
initialise when the runtime sees fit to do so (or is my mind in C++ land
again).

class Class2
{
    private readonly Class1 veryAnnoying = 0;

    public Class2()
    {
    }

Quote:
}

This leads me to the conclusion that the definition of readonly that I read
was innacurate and also that you cannot
make class fields constant unless they are of built in value type or
reference, I don't see anyway of initialising anything
else.

Andrew



Fri, 14 Jan 2005 23:34:29 GMT  
 Problems assigning const fields in a class to an initial value
Andrew,

    The problem is that const is just that, a constant field.  You are not
to be able to change it at runtime at all.

    Your best bet would be to declare the field as readonly and to
initialize it in the static constructor, as you said.  This static
constructor will be called when the type is referenced in any way.  So, if
an instance of your type is created, or another static property is
referenced, then the static constructor is called.

    Hope this helps.

--
               - Nicholas Paldino [.NET MVP]

    To get around this, declare the variable as static and read only.  That
way, you can assign

Quote:
> I am an experienced C++ developer and am embarking of my first project to
> make serious use of C#.
> Generaly the transition so far has been smooth, just a change of mindset (
> e.g. I can't overide operator= anymore :-) ).

> I have run into an issue with const fields on a class though.

> e.g.

> class Class1
> {
>     private int xVal;
>     private int yVal;

>     public Class1(int xVal, int yVal)
>     {
>         this.xVal = xVal;
>         this.yVal = yVal;
>     }
> }

> class Class2
> {
>     private const Class1 veryAnnoying;

>     public Class2()
>     {
>     }
> }

> Now clearly this doesn't compile as Class1 needs to be initialised to
> something.

> OK

> class Class2
> {
>     private const Class1 veryAnnoying = 0;

>     public Class2()
>     {
>     }
> }

> Clearly doesn't work either as the compiler cannot assign 0 to my class,
so
> I add an implicit
> casting operator to Class1 to cast from int to Class1.

> class Class1
> {
>     private int xVal;
>     private int yVal;

>     public Class1(int xVal, int yVal)
>     {
>         this.xVal = xVal;
>         this.yVal = yVal;
>     }

>     public static implicit operator Class1(int val)
>     {
>         return new Class1(val, val);
>     }
> }

> Now the compiler complains that the value, 0, that I am assigning to the
> private field is not const, er yes it is!

> class Class2
> {
>     private const Class1 veryAnnoying = 0;

>     public Class2()
>     {
>     }
> }

> Now if I change the modifier from const to readonly then it compiles, but
my
> understanding is that readonly's only
> difference to const it that it lets you initialise the the class field in
> your constructor.  A const or readonly member
> initialised in the way I am doing does not initialise in my constructor
they
> initialise when the runtime sees fit to do so (or is my mind in C++ land
> again).

> class Class2
> {
>     private readonly Class1 veryAnnoying = 0;

>     public Class2()
>     {
>     }
> }

> This leads me to the conclusion that the definition of readonly that I
read
> was innacurate and also that you cannot
> make class fields constant unless they are of built in value type or
> reference, I don't see anyway of initialising anything
> else.

> Andrew



Fri, 14 Jan 2005 23:38:43 GMT  
 Problems assigning const fields in a class to an initial value
I've just taken another look at the documentation and everything has become
clear (isn't it amazing how just
typing the problem out fixes it).

This is what I find in MSDN const definition, indicating that const has the
same semantics whether working
on a field or a local variable and that it only works on built-in value
types, enums and references.

[type]
    One of the types: byte, char, short, int, long, float, double, decimal,
bool, string, an enum type, or a reference type.

Defining a value const for optimisation reasons as I would do in C++ is
obviouly no longer valid in the CLR (it seems), I would
still like to be able to declare a class instance immutable however, C#
won't let me, can anyone offer me a decent
reason why not so I can adjust my mindset accordingly!!

There is a {*filter*} way around it by creating a non const class class which has
a readonly field to the class you want const,
effectively a const wrapper, but that's a bit much and obviously indicates
your doing something wrong.

Andrew


Quote:
> I am an experienced C++ developer and am embarking of my first project to
> make serious use of C#.
> Generaly the transition so far has been smooth, just a change of mindset (
> e.g. I can't overide operator= anymore :-) ).

> I have run into an issue with const fields on a class though.

> e.g.

> class Class1
> {
>     private int xVal;
>     private int yVal;

>     public Class1(int xVal, int yVal)
>     {
>         this.xVal = xVal;
>         this.yVal = yVal;
>     }
> }

> class Class2
> {
>     private const Class1 veryAnnoying;

>     public Class2()
>     {
>     }
> }

> Now clearly this doesn't compile as Class1 needs to be initialised to
> something.

> OK

> class Class2
> {
>     private const Class1 veryAnnoying = 0;

>     public Class2()
>     {
>     }
> }

> Clearly doesn't work either as the compiler cannot assign 0 to my class,
so
> I add an implicit
> casting operator to Class1 to cast from int to Class1.

> class Class1
> {
>     private int xVal;
>     private int yVal;

>     public Class1(int xVal, int yVal)
>     {
>         this.xVal = xVal;
>         this.yVal = yVal;
>     }

>     public static implicit operator Class1(int val)
>     {
>         return new Class1(val, val);
>     }
> }

> Now the compiler complains that the value, 0, that I am assigning to the
> private field is not const, er yes it is!

> class Class2
> {
>     private const Class1 veryAnnoying = 0;

>     public Class2()
>     {
>     }
> }

> Now if I change the modifier from const to readonly then it compiles, but
my
> understanding is that readonly's only
> difference to const it that it lets you initialise the the class field in
> your constructor.  A const or readonly member
> initialised in the way I am doing does not initialise in my constructor
they
> initialise when the runtime sees fit to do so (or is my mind in C++ land
> again).

> class Class2
> {
>     private readonly Class1 veryAnnoying = 0;

>     public Class2()
>     {
>     }
> }

> This leads me to the conclusion that the definition of readonly that I
read
> was innacurate and also that you cannot
> make class fields constant unless they are of built in value type or
> reference, I don't see anyway of initialising anything
> else.

> Andrew



Fri, 14 Jan 2005 23:47:53 GMT  
 Problems assigning const fields in a class to an initial value
Thanks Nicholas

This is definitely a case of mindset adjustment and probably C++ misuse of
const, you'll see i've updated my original post
and I think that combined with what your saying below fully answers my
question.

Essentialy the following which would work fine in C++ cannot be done.

const Class1 instance = 0;

because it is executing code at some point at runtime to initialise itself,
wheras;

const int x = 0;

never executes code at runtime to initialise itself, it's fixed at compile
time.

Andrew



Quote:
> Andrew,

>     The problem is that const is just that, a constant field.  You are not
> to be able to change it at runtime at all.

>     Your best bet would be to declare the field as readonly and to
> initialize it in the static constructor, as you said.  This static
> constructor will be called when the type is referenced in any way.  So, if
> an instance of your type is created, or another static property is
> referenced, then the static constructor is called.

>     Hope this helps.

> --
>                - Nicholas Paldino [.NET MVP]

>     To get around this, declare the variable as static and read only.
That
> way, you can assign


> > I am an experienced C++ developer and am embarking of my first project
to
> > make serious use of C#.
> > Generaly the transition so far has been smooth, just a change of mindset
(
> > e.g. I can't overide operator= anymore :-) ).

> > I have run into an issue with const fields on a class though.

> > e.g.

> > class Class1
> > {
> >     private int xVal;
> >     private int yVal;

> >     public Class1(int xVal, int yVal)
> >     {
> >         this.xVal = xVal;
> >         this.yVal = yVal;
> >     }
> > }

> > class Class2
> > {
> >     private const Class1 veryAnnoying;

> >     public Class2()
> >     {
> >     }
> > }

> > Now clearly this doesn't compile as Class1 needs to be initialised to
> > something.

> > OK

> > class Class2
> > {
> >     private const Class1 veryAnnoying = 0;

> >     public Class2()
> >     {
> >     }
> > }

> > Clearly doesn't work either as the compiler cannot assign 0 to my class,
> so
> > I add an implicit
> > casting operator to Class1 to cast from int to Class1.

> > class Class1
> > {
> >     private int xVal;
> >     private int yVal;

> >     public Class1(int xVal, int yVal)
> >     {
> >         this.xVal = xVal;
> >         this.yVal = yVal;
> >     }

> >     public static implicit operator Class1(int val)
> >     {
> >         return new Class1(val, val);
> >     }
> > }

> > Now the compiler complains that the value, 0, that I am assigning to the
> > private field is not const, er yes it is!

> > class Class2
> > {
> >     private const Class1 veryAnnoying = 0;

> >     public Class2()
> >     {
> >     }
> > }

> > Now if I change the modifier from const to readonly then it compiles,
but
> my
> > understanding is that readonly's only
> > difference to const it that it lets you initialise the the class field
in
> > your constructor.  A const or readonly member
> > initialised in the way I am doing does not initialise in my constructor
> they
> > initialise when the runtime sees fit to do so (or is my mind in C++ land
> > again).

> > class Class2
> > {
> >     private readonly Class1 veryAnnoying = 0;

> >     public Class2()
> >     {
> >     }
> > }

> > This leads me to the conclusion that the definition of readonly that I
> read
> > was innacurate and also that you cannot
> > make class fields constant unless they are of built in value type or
> > reference, I don't see anyway of initialising anything
> > else.

> > Andrew



Fri, 14 Jan 2005 23:54:34 GMT  
 Problems assigning const fields in a class to an initial value
Andrew,

Quote:
> const Class1 instance = 0;

    The above works fine because pointers can be set to 0, which is really
aliased in C with NULL.  In C#, there is a distinct difference (in the
language) between null and 0, and you have to handle that, so the above
should really be:

const Class1 instance = null;

--
               - Nicholas Paldino [.NET MVP]


Quote:
> Thanks Nicholas

> This is definitely a case of mindset adjustment and probably C++ misuse of
> const, you'll see i've updated my original post
> and I think that combined with what your saying below fully answers my
> question.

> Essentialy the following which would work fine in C++ cannot be done.

> const Class1 instance = 0;

> because it is executing code at some point at runtime to initialise
itself,
> wheras;

> const int x = 0;

> never executes code at runtime to initialise itself, it's fixed at compile
> time.

> Andrew


wrote

> > Andrew,

> >     The problem is that const is just that, a constant field.  You are
not
> > to be able to change it at runtime at all.

> >     Your best bet would be to declare the field as readonly and to
> > initialize it in the static constructor, as you said.  This static
> > constructor will be called when the type is referenced in any way.  So,
if
> > an instance of your type is created, or another static property is
> > referenced, then the static constructor is called.

> >     Hope this helps.

> > --
> >                - Nicholas Paldino [.NET MVP]

> >     To get around this, declare the variable as static and read only.
> That
> > way, you can assign


> > > I am an experienced C++ developer and am embarking of my first project
> to
> > > make serious use of C#.
> > > Generaly the transition so far has been smooth, just a change of
mindset
> (
> > > e.g. I can't overide operator= anymore :-) ).

> > > I have run into an issue with const fields on a class though.

> > > e.g.

> > > class Class1
> > > {
> > >     private int xVal;
> > >     private int yVal;

> > >     public Class1(int xVal, int yVal)
> > >     {
> > >         this.xVal = xVal;
> > >         this.yVal = yVal;
> > >     }
> > > }

> > > class Class2
> > > {
> > >     private const Class1 veryAnnoying;

> > >     public Class2()
> > >     {
> > >     }
> > > }

> > > Now clearly this doesn't compile as Class1 needs to be initialised to
> > > something.

> > > OK

> > > class Class2
> > > {
> > >     private const Class1 veryAnnoying = 0;

> > >     public Class2()
> > >     {
> > >     }
> > > }

> > > Clearly doesn't work either as the compiler cannot assign 0 to my
class,
> > so
> > > I add an implicit
> > > casting operator to Class1 to cast from int to Class1.

> > > class Class1
> > > {
> > >     private int xVal;
> > >     private int yVal;

> > >     public Class1(int xVal, int yVal)
> > >     {
> > >         this.xVal = xVal;
> > >         this.yVal = yVal;
> > >     }

> > >     public static implicit operator Class1(int val)
> > >     {
> > >         return new Class1(val, val);
> > >     }
> > > }

> > > Now the compiler complains that the value, 0, that I am assigning to
the
> > > private field is not const, er yes it is!

> > > class Class2
> > > {
> > >     private const Class1 veryAnnoying = 0;

> > >     public Class2()
> > >     {
> > >     }
> > > }

> > > Now if I change the modifier from const to readonly then it compiles,
> but
> > my
> > > understanding is that readonly's only
> > > difference to const it that it lets you initialise the the class field
> in
> > > your constructor.  A const or readonly member
> > > initialised in the way I am doing does not initialise in my
constructor
> > they
> > > initialise when the runtime sees fit to do so (or is my mind in C++
land
> > > again).

> > > class Class2
> > > {
> > >     private readonly Class1 veryAnnoying = 0;

> > >     public Class2()
> > >     {
> > >     }
> > > }

> > > This leads me to the conclusion that the definition of readonly that I
> > read
> > > was innacurate and also that you cannot
> > > make class fields constant unless they are of built in value type or
> > > reference, I don't see anyway of initialising anything
> > > else.

> > > Andrew



Sat, 15 Jan 2005 00:03:28 GMT  
 Problems assigning const fields in a class to an initial value
Oh of course sure but i'm not interested in assigning the class to NULL or
0, I use 0 below but the number
could easily be 5 or 10.  What I want to do is construct the class properly
and then from that moment onwards
it is not changable.

e.g. in C++ the following works fine, the classes are fully initialised and
immutable

const SomeClass someClassInstance(1, 2);

or

class ConsumingClass
{
    ConsumingClass(int x, int y)
    :    m_SomeClass(x, y)
    { }

protected:
    const SomeClass m_SomeClass;

Quote:
};

In the .NET/C# world I now understand that I cannot do this because code has
to run to do this and as far as .NET/C# is concerned
you can only use const where everything is fixed at compile time and no code
needs to execute at runtime.  Hence for built in types, enums
and references it works, also assigning const class objects to NULL works
because no code needs to be executed.

The only variation is with readonly that lets initialisation code run in the
consuming classes constructor.

The meaning of const is clearly different in .NET using it for optimisation
reasons as I would in C++ is not required.
It is still usefull to be able to create const immutable instances of
variables.
How else, apart from comments, do you indicate that the variable is
immutable and stop other coders whilst maintaining
your code assigning the variable to something else later or elsewhere and
breaking functionality?

e.g. in C++

const SomeClass someClassInstance(1, 2);
...
...
someClassInstance.ChangeSomething();    // Generates an error, alerts coder
they are doing something wrong.

in .NET/C# you cannot do this, I guess I am going to have to get used to it,
it just sounds like you cannot do this because
of the way the framework works rather than nice language practice (or at
least what I am used to).

Thanks
Andrew



Quote:
> Andrew,

> > const Class1 instance = 0;

>     The above works fine because pointers can be set to 0, which is really
> aliased in C with NULL.  In C#, there is a distinct difference (in the
> language) between null and 0, and you have to handle that, so the above
> should really be:

> const Class1 instance = null;

> --
>                - Nicholas Paldino [.NET MVP]



> > Thanks Nicholas

> > This is definitely a case of mindset adjustment and probably C++ misuse
of
> > const, you'll see i've updated my original post
> > and I think that combined with what your saying below fully answers my
> > question.

> > Essentialy the following which would work fine in C++ cannot be done.

> > const Class1 instance = 0;

> > because it is executing code at some point at runtime to initialise
> itself,
> > wheras;

> > const int x = 0;

> > never executes code at runtime to initialise itself, it's fixed at
compile
> > time.

> > Andrew


> wrote

> > > Andrew,

> > >     The problem is that const is just that, a constant field.  You are
> not
> > > to be able to change it at runtime at all.

> > >     Your best bet would be to declare the field as readonly and to
> > > initialize it in the static constructor, as you said.  This static
> > > constructor will be called when the type is referenced in any way.
So,
> if
> > > an instance of your type is created, or another static property is
> > > referenced, then the static constructor is called.

> > >     Hope this helps.

> > > --
> > >                - Nicholas Paldino [.NET MVP]

> > >     To get around this, declare the variable as static and read only.
> > That
> > > way, you can assign


> > > > I am an experienced C++ developer and am embarking of my first
project
> > to
> > > > make serious use of C#.
> > > > Generaly the transition so far has been smooth, just a change of
> mindset
> > (
> > > > e.g. I can't overide operator= anymore :-) ).

> > > > I have run into an issue with const fields on a class though.

> > > > e.g.

> > > > class Class1
> > > > {
> > > >     private int xVal;
> > > >     private int yVal;

> > > >     public Class1(int xVal, int yVal)
> > > >     {
> > > >         this.xVal = xVal;
> > > >         this.yVal = yVal;
> > > >     }
> > > > }

> > > > class Class2
> > > > {
> > > >     private const Class1 veryAnnoying;

> > > >     public Class2()
> > > >     {
> > > >     }
> > > > }

> > > > Now clearly this doesn't compile as Class1 needs to be initialised
to
> > > > something.

> > > > OK

> > > > class Class2
> > > > {
> > > >     private const Class1 veryAnnoying = 0;

> > > >     public Class2()
> > > >     {
> > > >     }
> > > > }

> > > > Clearly doesn't work either as the compiler cannot assign 0 to my
> class,
> > > so
> > > > I add an implicit
> > > > casting operator to Class1 to cast from int to Class1.

> > > > class Class1
> > > > {
> > > >     private int xVal;
> > > >     private int yVal;

> > > >     public Class1(int xVal, int yVal)
> > > >     {
> > > >         this.xVal = xVal;
> > > >         this.yVal = yVal;
> > > >     }

> > > >     public static implicit operator Class1(int val)
> > > >     {
> > > >         return new Class1(val, val);
> > > >     }
> > > > }

> > > > Now the compiler complains that the value, 0, that I am assigning to
> the
> > > > private field is not const, er yes it is!

> > > > class Class2
> > > > {
> > > >     private const Class1 veryAnnoying = 0;

> > > >     public Class2()
> > > >     {
> > > >     }
> > > > }

> > > > Now if I change the modifier from const to readonly then it
compiles,
> > but
> > > my
> > > > understanding is that readonly's only
> > > > difference to const it that it lets you initialise the the class
field
> > in
> > > > your constructor.  A const or readonly member
> > > > initialised in the way I am doing does not initialise in my
> constructor
> > > they
> > > > initialise when the runtime sees fit to do so (or is my mind in C++
> land
> > > > again).

> > > > class Class2
> > > > {
> > > >     private readonly Class1 veryAnnoying = 0;

> > > >     public Class2()
> > > >     {
> > > >     }
> > > > }

> > > > This leads me to the conclusion that the definition of readonly that
I
> > > read
> > > > was innacurate and also that you cannot
> > > > make class fields constant unless they are of built in value type or
> > > > reference, I don't see anyway of initialising anything
> > > > else.

> > > > Andrew



Sat, 15 Jan 2005 00:59:53 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. Assigning initial values to private variables in a class

2. const struct ** x = (initial value);

3. Q: Assigning values to const struct*

4. Problems in assigning with const attribute

5. Problem passing char * to a function where it is assigned its value

6. How to get the value of a counter (AutoIncrement) field using MFC DAO classes

7. howto: getting field value with DAO classes

8. howto: getting field value with DAO classes

9. How to get the value of a counter (AutoIncrement) field using MFC DAO classes

10. HELP: Problem with Recordset->Fields(index)->Value

11. Update record Field value problem

12. assigning to const int allowed?

 

 
Powered by phpBB® Forum Software