Why does a client code need to be recompiled also?

B

beginwithl

Hi

I’ve started learning C# just a few days ago and things already got a
bit confusing.


BTW - I hope I'm not breaking any rules by putting three questions
inside a single thread, but I don’t want to "spam" this forum with
even more threads



1) From the book:

“A field initializer is part of the field declaration, and consists of
an equals sign followed by an expression that evaluates to a value.
The initialization value must be determinable at compile time.”

But if initialization value must indeed be determinable at compile
time, then the following code would produce an error, due to the fact
that here the initialization value can’t be known at compile time,
since memory on the heap is only allocated at run-time:

class A
{
B b = new B(); // here value of b can't be known until run time
}





2) The following quote talks about about the usefulness of auto-
implemented properties:

“Besides being convenient, auto-implemented properties allow you to
easily insert a property where you might be tempted to declare a
public field.
You might, however, be tempted to release a version of the code with a
public field, and then in a later release change the field to a
property. However, the semantics of a compiled variable and a compiled
property are different. If, in a later release, you were to switch
from a field to a property, any assemblies accessing that field in the
first release would have to be recompiled to use the property. If you
use a property in the first place, the client doesn’t have to be
recompiled.”


Say I created class X, the member of which is also a public instance
field named A, and put this class into assembly. Now some third party
writes a code that access this field A. Later I decide to replace
public field A with public property called A ( of same type as field
was ), so I rewrite and recompile my class.
As far as I can tell, client would still access this property A using
the same code as it used for accessing field A:

class X
{
public int A;
}

Client uses the following code to access field A:

void Main
{
...
X x = new X();
int i = x.A;
...
}

Say we now change class X to:

class X
{
public int A
{
get; set;
}
}


Client would still use the identical code to access A:

void Main
{
...
X x = new X();
int i = x.A;
...
}




3) If we declare constant A ( its value being 100 ), then compiler
doesn't place a constant A into an assembly, but rather puts just its
value directly into code.

Now, unlike constants, readonly fields do have an address in memory
and can be assigned a value at declaration or in constructor ( thus at
run time ).

* As such, I don’t understand what is gained by having constants at
all, since ‘readonly’ fields offer practically the same
functionality?!


thank you
 
J

Jeff Johnson

BTW - I hope I'm not breaking any rules by putting three questions
inside a single thread, but I don’t want to "spam" this forum with
even more threads

Although you may be accessing this via a Web interface, this is NOT a Web
forum. It is a USENET newsgroup, and therefore many of the "rules" you have
learned in Web forums do not apply here. For example, there is no stigma
against "double posting," although multiple posts on the same topic should
be kept in the same thread.

On the subject of threads: you have actually created three threads, not a
single thread as you believed. In a newsgroup, it is basically the subject
of the post that creates a thread (this is not REALLY the case, but it is
FUNCTIONALLY true). Creating three threads is a good thing when they all
have different topics.

As for your questions, I can really only answer one of them:
1) From the book:
“A field initializer is part of the field declaration, and consists of
an equals sign followed by an expression that evaluates to a value.
The initialization value must be determinable at compile time.”
But if initialization value must indeed be determinable at compile
time, then the following code would produce an error, due to the fact
that here the initialization value can’t be known at compile time,
since memory on the heap is only allocated at run-time:
class A
{
B b = new B(); // here value of b can't be known until run time
}

You're wrong in your assumption that the "value of b can't be known until
run time." In fact, I'm not even sure what you're saying. At run time, b
will be initialized as a new instance of class B. In other words, the
statement above will compile and execute perfectly.
 
R

RayLopez99

Hi

I’ve started learning C# just a few days ago and things already got a
bit confusing.

BTW - I hope I'm not breaking any rules by putting three questions
inside a single thread, but I don’t want to "spam" this forum with
even more threads

Don't worry about SPAM--trust me on this.
1) From the book:

“A field initializer is part of the field declaration, and consists of
an equals sign followed by an expression that evaluates to a value.
The initialization value must be determinable at compile time.”

But if initialization value must indeed be determinable at compile
time, then the following code would produce an error, due to the fact
that here the initialization value can’t be known at compile time,
since memory on the heap is only allocated at run-time:

class A
{
     B b = new B(); // here value of  b can't be known until run time

}

Why not? The value seems to be the default (normal) constructor. If
one is not provided I think the compiler provides one. So your book
is just arguing over semantics. I say "forget the theory, just code!"
but others might disagree.

2) The following quote talks about about the usefulness of auto-
implemented properties:

“Besides being convenient, auto-implemented properties allow you to
easily insert a property where you might be tempted to declare a
public field.
You might, however, be tempted to release a version of the code with a
public field, and then in a later release change the field to a
property. However, the semantics of a compiled variable and a compiled
property are different. If, in a later release, you were to switch
from a field to a property, any assemblies accessing that field in the
first release would have to be recompiled to use the property. If you
use a property in the first place, the client doesn’t have to be
recompiled.”

Beats me... too many words... properties are good though, kinda like
public variables. you can also do stuff live public get and private
set.

Say I created class X, the member of which is also a public instance
field named A, and put this class into assembly. Now some third party
writes a code that access this field A. Later I decide to replace
public field A with public property called A ( of same type as field
was ), so I rewrite and recompile my class.
As far as I can tell, client would still access this property A using
the same code as it used for accessing field A:

class X
{
  public int A;

}

Client uses the following code to access field A:

void Main
{
        ...
    X x = new X();
    int i = x.A;
        ...

}

Say we now change class X to:

class X
{
    public int A
   {
         get; set;
    }

}

Client would still use the identical code to access A:

void Main
{
        ...
   X x = new X();
   int i = x.A;
        ...

}

3) If we declare constant A ( its value being 100 ), then compiler
doesn't place a constant A into an assembly, but rather puts just its
value directly into code.

Now, unlike constants, readonly fields do have an address in memory
and can be assigned a value at declaration or in constructor ( thus at
run time ).

* As such, I don’t understand what is gained by having constants at
all, since ‘readonly’ fields offer practically the same
functionality?!

Beats me. But C# does not really have "readonly". In fact, the
'readonly' is more like "read once and never change", kind of like a
macro constant or DEFINE in C. I hardly use them. To really do "read
only" like in C++, you have to set up a copy, using a form of copy
constructor in C# that employs serialization (deep and shallow
copies). Too complicated to get into in this thread, and usually you
don't really need them anyway (just copy the references to another
object).

Hope this helps...the hard stuff in C# is the delegates/events (a sort
of global goto variable of sorts)...everything else is easy... LINQ
looks hard but is easy. In one month you'll feel like a master, and
in six to nine months you'll be a guru... don't expect to equal this
board's real gurus though, like Goran and FTM and Jon Skeet and Peter
Dungho, those guys are really good, but I would argue that you don't
really have to be as good as them to write competent code in C#.

RL
thank you

you're welcome
 
S

Sebastian Hungerecker

Jeff said:
In a newsgroup, it is basically the subject
of the post that creates a thread (this is not REALLY the case, but it is
FUNCTIONALLY true).

What makes you say that? This message has a completely different
subject-line than yours, but it is still part of the same thread
(and should be displayed as such by any decent newsreader).
 
J

Jeff Johnson

What makes you say that? This message has a completely different
subject-line than yours, but it is still part of the same thread
(and should be displayed as such by any decent newsreader).

Some newsreaders, like the one I'm using (which I'm sure you would NOT
consider a "decent newsreader") will merge two threads if the subject lines
are the same. At least OE doesn't split apart a thread when the subject is
changed....
 
M

Michael Starberg

Peter Duniho said:
As you probably are aware, this works fine.

However, the books talks about field initializers, not constructing objects.
I think the book is trying to say this:

Class A
{
private int number = 5; // right side must be determinable at
compile-time.
}

Regards
- Michael Starberg
 
J

Jeff Johnson

However, the books talks about field initializers, not constructing
objects.
I think the book is trying to say this:

Class A
{
private int number = 5; // right side must be determinable at
compile-time.
}

"Initializing a field" means setting it to a value when it is declared,
whether that value be a simple integer or a constructed object. So either
way a field initialization is taking place.
 
B

beginwithl

hi
From what book?

Illustrated C#

I would say that strictly speaking, that's not true.


As you probably are aware, this works fine. And you're right, technically
speaking, the value of "b", being a reference to an instance of B, cannot
be known until run-time. So the exact language the book uses is incorrect..

Could you make an educated guess about what the author was most likely
trying to convey?


The functionality is similar, but different in a crucial way: as you've
noted, a "const" field is a compile-time thing only. Whatever the
definition of the "const" field at the time that the _client_ is compiled,
that's the value that's used.

If you instead declare a read-only field, then the value of the field
isn't even determined until run-time. All the client code knows is that
there's a field it has to read. This means that if the library declaring
the field wants to change the value in the future, it can without needing
for client code to be recompiled.

In fact, whether this is an advantage or not really depends on the
situation. Sometimes you want the value to be determined at compile-time,
locked in forever until the code is recompiled. In that case, "const" is
the appropriate modifier.


Ah, I forgot that if client code accesses a constant defined in some
external assembly, then when this client code is compiled, it is the
value of constant and not the constant reference that is hardcoded
into this client assembly.




2) The following quote talks about the usefulness of auto-
implemented properties: [...]
As far as I can tell, client would still access this property A using
the same code as it used for accessing field A:

class X
{
public int A;
}

Client uses the following code to access field A:

void Main
{
...
X x = new X();
int i = x.A;
...
}

The syntax is identical, yes. But what's generated by the compiler is
completely different. In the case of the field, the compiled code simply
dereferences the object and accesses the field. In the case of the
property, the compiled code calls the "get" method of the property to
retrieve the value.

So if you change from a field to a property, you _must_ recompile the
client code so that it performs the appropriate action, even though the
syntax is the same.


This is a bit off topic, but why couldn’t the assembly containing
class X also contain code that generates a call to “get” method of a
property A? Wouldn’t in that case the encapsulation be even more
effective, since now we could freely replace a field with a property
( assuming they both have the same name and type), without the need
for the client code to be recompiled?




You're wrong in your assumption that the "value of b can't be known until
run time." In fact, I'm not even sure what you're saying. At run time, b
will be initialized as a new instance of class B. In other words, the
statement above will compile and execute perfectly.

Value of “b” holds a reference to the object ( of type B ) located on
the heap. And this object won’t be created until run time, so how
could a value of “b” be known at compile time?!



thank you
 
M

Michael Starberg

Jeff Johnson said:
"Initializing a field" means setting it to a value when it is declared,
whether that value be a simple integer or a constructed object. So either
way a field initialization is taking place.

Yes, but "field initializers" is a language feature in C#.
Try to do the above in Java, and it won't compile; but becuase C# sports
field initializers, you can.

10.4.5.2 Instance field initialization:
http://msdn.microsoft.com/en-us/library/aa645759(VS.71).aspx

Regards
- Michael Starberg
 
B

beginwithl

hi

Sorry for not replying sooner but I had some problems with my PC.
Anyways:
[...]
Could you make an educated guess about what the author was most likely
trying to convey?

The author may in fact not be familiar with the rules. It wouldn't be the
first time someone published a programming book written by someone who has
some gaps in their knowledge.

As far as what might have led him to write such a thing, even if his
intended point was wrong, there are in fact restrictions on what you can
put in a type's field initializer. In particular, you cannot do things
that would be undefined at the moment that the initializer is executed.
The big no-no would be referring to any instance members, since the
initializer is executed before _all_ of the constructors, so there's no
safe way to ensure that an instance method would execute correctly.

The C# specification, difficult to read but the only definitive reference,
has all the specifics if you're more curious. My feeling, without having
a copy of the book in hand, is that the author simply didn't double-check
his facts and did in fact intend to convey the point you inferred, wrong
though it was.


I also did the folowing and it worked, so as far as I’m concerned, the
initialization value of a field can be determined at run time:

class A
{
public int a = 160;
public int u()
{
return 1600;
}
}

class B : A
{
public int i = new A().u();
}


Anyways, I really appreciate all your help

bye
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top