Inherited Readonly Members

G

Guest

I have a field in an abstract class marked readonly. However, when I attempt
to modify that field in the constructor of a class which inherits it, I get a
compile-time error stating that 'A readonly field cannot be assigned to
(except in a constructor or a variable initializer).' Any ideas would be
apreciated, though I was hoping I wouldn't have to use a property.
Reuben.
 
T

Tim Haughton

It can only be changed in the containing classes constructor, or in its
variable initializer. Private (non readonly) field, protected set method
would do the same, yes?

Regards,

Tim Haughton
 
C

Chad Z. Hower aka Kudzu

Tim Haughton said:
It can only be changed in the containing classes constructor, or in its
variable initializer. Private (non readonly) field, protected set method
would do the same, yes?

You dont need a set method, you can just access the field directly if you declare it protected.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Empower ASP.NET with IntraWeb
http://www.atozed.com/IntraWeb/
 
H

Helge Jensen

Reuben said:
I have a field in an abstract class marked readonly. However, when I attempt
to modify that field in the constructor of a class which inherits it, I get a

readonly means that the member can only be assigned to in the
constructor (or by an initialization expression).

But, in your case you can pass it's value to the parent constructor:

class Foo {
readonly int x;
protected Foo(..., int x) { ...; }
}
class Bar: Foo {
public static int calculate_x(object args) { ...; return 0; }
public Bar(..., object args): base(..., calculate_x(args)) { ...; }
}
 
J

Jon Skeet [C# MVP]

Chad Z. Hower aka Kudzu said:
You dont need a set method, you can just access the field directly if
you declare it protected.

Yes, if you don't believe (as I do) that fields should pretty much
*always* be private, with protected properties allowing access to
derived classes :)
 
F

Frisky

You can call the base constructor with a value and initialize it in the base
class.

for example:

public class One
{
private readonly int _number;
public One(int number)
{
_number = number;
}
}

public class Two : One
{
public Two(int number) : base(number)
{
}
}

Hope this helps...

Frisky
 
C

Chad Z. Hower aka Kudzu

Jon Skeet said:
Yes, if you don't believe (as I do) that fields should pretty much
*always* be private, with protected properties allowing access to
derived classes :)

Thats not always a good method. There is a more common practice of making fields only private or
protected, and all pulbic interfaces as properties. Applying this a level higher though just adds
codes to descendants in many cases.



--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Get your ASP.NET in gear with IntraWeb!
http://www.atozed.com/IntraWeb/
 
J

Jon Skeet [C# MVP]

Chad Z. Hower aka Kudzu said:
Thats not always a good method. There is a more common practice of
making fields only private or protected, and all pulbic interfaces as
properties. Applying this a level higher though just adds codes to
descendants in many cases.

Microsoft's guidelines disagree with you :)

http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/cpgenref/html/cpconfieldusageguidelines.asp

"Do not use instance fields that are public or protected (Public or
Protected in Visual Basic). If you avoid exposing fields directly to
the developer, classes can be versioned more easily because a field
cannot be changed to a property while maintaining binary
compatibility."

Basically, the exact same reasons for avoiding public fields apply to
protected fields in my view.
 
C

Chad Z. Hower aka Kudzu

Jon Skeet said:
Microsoft's guidelines disagree with you :)

Its not the only one I disagree with. :) Guidelines are just that, guidelines.

In fact I dont use privates at all - I realize this is heresy to many but we do a lot of inheriting
within our own frameworks and too often I've inherited someone elses object and very few
developers understand when to make something private and when to make it protected - and those
that do rarely sit and think about each declaration. Too often things that are private should be
protected (Fields, methods, properties). If its all protected - it can be inherited from. If you dont
intend your class to be inherited from, seal it.
"Do not use instance fields that are public or protected (Public or
Protected in Visual Basic). If you avoid exposing fields directly to
the developer, classes can be versioned more easily because a field
cannot be changed to a property while maintaining binary
compatibility."

The part they dont state is that doing so in many cases adds significant overhead, and if the
developer really doesnt undersand what they are doing and blindly follows this then those
inheriting from their class will have real problems.

Such advice is fine for final classes, but if its intended to be inherited from its bad advice to be
followed as a rule.

If you look at type datasets, or troll around with reflector you will see that in some cases
Microsoft does not follow consistent guildelins themselves, and certainly when they do they
are not using the same ones they have published for others. I suspect that those that published
these guidelines are different and simply provided some basic starts and tips for others since
many users do not know where to start.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Develop ASP.NET applications easier and in less time:
http://www.atozed.com/IntraWeb/
 
J

Jon Skeet [C# MVP]

Chad Z. Hower aka Kudzu said:
Its not the only one I disagree with. :) Guidelines are just that, guidelines.

In fact I dont use privates at all - I realize this is heresy to many
but we do a lot of inheriting within our own frameworks and too often
I've inherited someone elses object and very few developers
understand when to make something private and when to make it
protected - and those that do rarely sit and think about each
declaration. Too often things that are private should be protected
(Fields, methods, properties). If its all protected - it can be
inherited from. If you dont intend your class to be inherited from,
seal it.

Indeed, and I'd argue that classes should be sealed by default just
like methods are non-virtual by default. I find that inheritance should
be used far less frequently than it tends to be.

Versioning makes a huge difference here - if you've got nothing
private, then you pretty much can't refactor anything without breaking
an existing version. I'd find that unnecessarily restrictive.
The part they dont state is that doing so in many cases adds
significant overhead, and if the developer really doesnt undersand
what they are doing and blindly follows this then those inheriting
from their class will have real problems.

In some cases it adds significant overhead, but I'd say that's pretty
rare.
Such advice is fine for final classes, but if its intended to be
inherited from its bad advice to be followed as a rule.

If you look at type datasets, or troll around with reflector you will
see that in some cases Microsoft does not follow consistent
guildelins themselves, and certainly when they do they are not using
the same ones they have published for others. I suspect that those
that published these guidelines are different and simply provided
some basic starts and tips for others since many users do not know
where to start.

While I'd agree with most of that, this is one of the guidelines I
would really encourage to be followed on almost every occasion. The
exception for me is for occasional nested classes which are purely
there to encapsulate some data, and serve no purpose outside their
enclosing type. In those cases, having made the type itself private, I
don't feel so bad about making the fields internal so I can reference
them directly. Nothing else will ever be able to use the fields outside
the enclosing class, and it's easy enough to refactor that later on -
without the potential for breaking any other classes.
 

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