I have two questions:
1.) Why am I not supposed to have protected fields in a class
2.) consider the following example:
public class A { private int field; public int Field { get { // do some extra work here return field; } set { this.field = value; // do some extra work here } } } public class B : A { public B(int field) { // set the base.field here without doing the // extra work // of the set acessor } } |
If I do not expose the field as protected I would need to introduce protected SetField() and GetField() Mehtods for each field that avoid doing the extra work in the Public Property acessors What would be a good design for such a scenario

class design: protected fields
JamesJ
As an aside on this, my philosophy is that if you have work in the set accessor that is even mildly complicated or has side effects, it should be a method instead anyway (A.Field, in this case)
Not that this is a hard and fast rule by any means, but when people see a property, it is implied that it is a fast operation without side effects. so looking at the line "a.Field = 4" another person would probably pass by it when looking for perf problems, or odd interactions. However, "a.SetSomething()" or whatever looks like it does more work than a simple field set.
This is just personal opinion and all - just wanted to put that out there.
oolon
Hello...
Who says that you are not supposed to have protected fields in a class
They are there for exactly that reason. If you create a base-Class and want to be able to access the "private" members of the base, since using the setters might have some "adverse" effects. You should only consider if you really need it. You should always keep the scope of your fields to the smallest possible level, and protected vs private does raise the scope one "notch".
For example, i have a Database access base class, and inside it there is a protected connection field, since i only need to use it in the class i inherit from. I dont want to expose the connection to the outside world, since they should not "care" about it. The class also implements ITransaction so it might need to keep the transactin open over several commands (Thats why the connection is not scoped to the procedure level, but to the class level)
Inside my class i want to have full access to the connection and i want to be able to dispose it whenever i need (command without transaction done or transaction done)
Hope this makes sense as an example
Peter McEvoy
You can still have all the "functionality" you described by making the connection field private and expose protected acessors. But addtionaly you benefit from this encapsulation when you have to extend/change your code at a later time. Say for example you want to introduce some addtional logic (such as validation etc.) whenever the fields is accessed by derived types. You would have to change the signature of the class and therefore would break all code that derives from this class. Also you can not know what the user of your code does when deriving from your basecalls with the protected field. Therefore protected fields can bee seen as beeing public.
WayneSpangler
TedViste
Why not It is called encapsulation to make sure that the internal state of the object can be changed in a controlled manner.
You have 2 options:
1) In the constructor of the derived class call the constructor of the base class passing the values for the fields
public B(int field) : base(field)
base (C# Reference)
2) I would use protected property setters assuming that you are using C# 2.0. If not implement a protected Set method to set the field.
Asymmetric Accessor Accessibility (C# Programming Guide)
ChEngGeoSun
Well at the framework designguidelines say that you should not have protected fields and that they should be wrapped in protected property acessors or methods. The book "Framework Design Guidelines" by Brad Abrams states that too. *shrug*
Tony Hild
outcast1881
Dave,
I didn't say "no code" by any means, and I agree that prop change events are in place in a property accessor - but you hit it on the head with one sentence "The idea is they should logically appear as fields to the user of the class..."
If the I (as a user of a class) see "foo.ConnectTo = svr", I would not expect this statement to connect to a server - i'd expect it to change the behavior of the object when acted on (like calling "connect()" later). "foo.ConnectTo( svr);", on the other hand is much more obvious as an action. I would expect that call to actually connect to a server.
If doing something can take a while or has side effects, it most likely should be thought of as an action by definition. And asking an object to act should not look like setting an object's field.
I'm not sure what you mean in the rest - I'd say that there's only readability to worry about anyway (since properties are created and used as accessors, as you point out -- And in my mind, readability is king in most cases, especially to consumers of the class/assembly/etc)