How to make a field read only outside class - c#

I have the following class (example):
public class Dog
{
int numberOfTeeth;
public Dog()
{
countTeeth();
}
private void countTeeth()
{
this.numberOfTeeth = 5; //this dog has seen better days, apparently
}
}
After I create the dog object, it should have the number of teeth calculated. I'd like to be able to access that value without being able to modify it outside the class itself.
Dog d = new Dog();
int dogTeeth = d.numberOfTeeth; //this should be possible
d.numberOfTeeth = 10; //this should not
However, I can't figure out which access modifier will let me do this. I've tried all of the following:
If I make numberOfTeeth private, I cannot access it.
If I make numberOfTeeth protected internal, I can change this value outside the class.
If I make numberOfTeeth internal, I can change this value outside the class.
If I make numberOfTeeth protected, I cannot access it.
If I make numberOfTeeth public, I can change this value outside the class.
I also tried making it readonly but then was unable to set it outside the constructor.
Is there any access modifier which will allow me to do this? Or is there some other method of accomplishing this protection?

Create a property with a private setter:
public int NumberOfTeeth
{
get; private set;
}
Notice I changed it to Pascal Case to match most .NET style standards.

You can't do that. You can make the field read-only and make a method that returns its value. You can also make an auto-property with a public getter and a protected setter:
public int NumberOfTeeth { get; protected set; }

You should make the field private and create a read-only (no setter) public property:
public class Dog
{
private int numberOfTeeth;
public int NumberOfTeeth {get {return numberOfTeeth;}}
public Dog()
{
countTeeth();
}
private void countTeeth()
{
this.numberOfTeeth = 5; //this dog has seen better days, apparently
}
}

public class Dog
{
public int numberOfTeeth { get; private set; }
public Dog()
{
countTeeth();
}
}

Related

How to prevent direct access to the variable in a class?

In my class I have private variable, which I use inside the class only through get/set. Sometimes I forget, that I shouldn't use variable directly (even within the class) and must use get/set.
How to make that the only way to use a variable were get/set?
public class A {
int x;
public XVariable {
get { return x; }
set { x = value }
// some additional operations
}
void SomeMethod() {
x = 5; // no
XVariable = 5; // yes
}
}
C# has auto properties. No backing field needed in your code.
public class A {
public XVariable {
get;
set;
}
}
You can also have different access modifiers. Like if you want to only be able to set it from within the class.
public class A {
public XVariable {
get;
private set;
}
}
There won't be a backing field accessible from your code, but the compiler will generate one in the MSIL (what C# compiles to). You don't have to worry about that part though.
A potential downside Joe pointed out to auto props, sometimes you need to perform other actions (especially event handlers) in your property when you set something. But that's not possible with auto props. In that case, his answer would be more appropriate. But if that's not a concern for your use case, then my answer should be sufficient.
You can create a base class, and do all your real work in the derived class:
public class SomeBaseClass {
private int _x;
public int X { get { return _x; } set { _x = value; } }
}
public class DerivedClass : SomeBaseClass {
void DoSomething() {
// Does not have access to _x
}
}
Many people prefix their private variables with an underscore to help signify the variable is private. (Although it is a matter of opinion, some people like it and some don't) There is a bit more insight on this question.
You can however, scrap the field and use an auto property such as:
public XVariable { get; set; }
An auto property will store an anonymous backing field "out of view".

How to access private variables using { get; set; }

I'd like to create a class for my website with a lot of private variable.
I thought there was a solution not to write all the getters and setters for each variable, something like
private int confirmed { get; set; }
Is it the right way? ANd then, how do I access this value from outside the class?
I've tried .confirmed , I get the error saying that it's private (which I understand)
But more surprising, .getConfirmed() or getconfirmed() do not work either.
I thought that the { get; set; } would create implicitely those methods.
Can someone clarify this concern for me please?
You can declare your property as public, then mark the getter or setter individually as private:
public int confirmed { get; private set; }
That way, you can access confirmed outside of your defined class:
Console.WriteLine(myClass.confirmed); // This is OK
myClass.confirmed = "Nothing"; // Can't do this
And the only one who can set the value of confirmed is then MyClass:
public class MyClass {
public int confirmed { get; private set; }
public MyClass() {
this.confirmed = "This"; // This is fine as we have private access
}
}
You need to understand that,
private int confirmed { get; set; }
will be expanded to a set of private methods with a private backing field,
private int _confirmed;
private int confirmed_get()
{
return this._confirmed;
}
private void confirmed_set(int value)
{
this._confirmed = value;
}
Thus, marking the property private makes both the accessor and the mutator also private, which is why you cannot access them outside of the class. Also, these methods are not accessible at compile time, so calling instance.confirmed_get() is not permitted, only instance.confimed both to read and write to the property.
What you might want is to declare it public,
public int confirmed { get; set; }
where the behavior is similar (the field still is private), but both method are now public. As others have mention you can individually modify the get and set for readonly or writeonly type of behavior,
public int confirmed { get; private/protected set; }
or
public int confirmed { private/protected get; set; }
And one last thing, you should get into the habit of using camel case for propeties, e.g. Confirmed and lower camel case for fields, e.g. confirmed (some might even do _confirmed). It is a popular naming conventions to distinguish the two types, especially for consumers of the class.
how do I access this value from outside the class?
You can't (without reflection form trusted code). They're private. If you want the getter to be public but the setter private then do
public int confirmed { get; private set; }
I thought that the {get;set;} would create implicitly those methods.
It does, but they're not accessible at design time.
Just do this if you want to get it from outside the class.
public int confirmed { get; set; }
or you can go this route:
private int confirmed;
public int Confirmed
{
get { return confirmed }
set { confirmed = value; }
}
There are multiple ways to perform such action. Depending upon your requirements, you can choose any one method from below:
// Old Conventional - Statement body
public class SampleClass1
{
public bool CanAccessFromOutside
{
get { return _cannotAccessFromOutside; }
}
private bool _cannotAccessFromOutside;
private void DoSomething()
{
_cannotAccessFromOutside = true;
}
}
// Expression Bodied Property
public class SampleClass2
{
public bool CanAccessFromOutside => _cannotAccessFromOutside;
private bool _cannotAccessFromOutside;
private void DoSomething()
{
_cannotAccessFromOutside = true;
}
}
// Auto Property
public class SampleClass3
{
public bool CanAccessFromOutside { get; private set; }
private void DoSomething()
{
CanAccessedFromOutside = true;
}
}

c# correct way to access private constant on other class

If I have a class
public class Person
{
private const string MyConst = "SomeValue";
[MyAttribute(MyConst)]
public string Name {get;set;}
}
and inside other class I would like to access MyConst what would be the best way to do so, keeping all encapsulated? Is it correct Person class?
If you wish to access MyConst from another class then you are no longer encapsulating it. Adding properties or method calls around this will not mean it is encapsulated. It's a constant. It cannot change. So either its publicly accessible or it's not. If another class needs access, make it internal or public.
Anything else is somewhere between denial and a code smell.
It all depends on the protection you need on MyConst. If no body should be able to read or write this property other than Person then you shouldn't expose it through either Get or Set methods. If everybody can read but cant write this, then you can expose it through a read only property. If only one class (e.g. ClassB) can read it then you can provide a function in Person that takes a ClassB object and passes the private Const to it:
public class ClassB
{
private string ConstValue {get; set;}
public void SetConstValue(string constValue)
{
ConstValue = constValue;
}
public void GetConstFromPerson(Person p)
{
p.GetConstValue(this);
}
}
public class Person
{
private const string MyConst = "A";
public void GetConstValue(ClassB obj)
{
//todo: contract validations
obj.SetConstValue(MyConst);
}
}
[Edit]
Another solution is to define the constant as Internal and only have Person and CLassB in the assembly
make a public property that returns MyConst?
public string MyPublicConst {get{ return MyConst;} private set; } - but why do you want to do this?
You can have it public (Duh!), you can use a property to encapsulate it if you are planning on changing it from a constant to something else, or you could have a method that return it to you.
class Encapsulation{
private string a;
public string AccessValue(){
return a;
}
}
you can do that to any variable I think, for sure the simple ones.
This is a public method from the same class that returns the same value of the private string.
In that way you can get the value from outside the class without declare it as public.
To reach it from another class you can just write:
class Player{ string b = Encapsulaion.AccessValue()}

Can the get of a property be abstract and the set be virtual?

I have a base class like this:
public class Trajectory{
public int Count { get; set; }
public double Initial { get; set { Count = 1; } }
public double Current { get; set { Count ++ ; } }
}
So, I have code in the base class, which makes the set-s virtual, but the get-s must stay abstract. So I need something like this:
...
public double Initial { abstract get; virtual set { Count = 1; } }
...
But this code gives an error.
The whole point is to implement the counter functionality in the base class instead in all the derived classes.
So, how can I make the get and set of a property with different modifiers?
split it into 2 functions:
public double Initial
{
get { return GetInitial(); }
set { SetInitial(value); }
}
protected virtual void SetInitial(double value)
{
Count = 1;
}
protected abstract double GetInitial();
Make it neither abstract nor virtual. And make the backing field private. That way, a derived class cannot override it nor can it mess with it.
No, you can't. At least I haven't found a solution.
If property is marked as abstract then neither it's getter and setter can have bodies.

C# Inheritance question

I have a class that has private fields... (cars)
I then inherit from this class... (Audi)
In the (Audi) class, when I type this. in the constructor...
the private fields are not available...
Do I need to do anything special to expose this private fields in (cars) class so that they are accessible via this. in (Audi class)?
One (bad) option is to make the fields protected - but don't do this; it still breaks proper encapsulation. Two good options:
make the setter protected
provide a constructor that accepts the values
examples:
public string Name { get; protected set; }
(C# 2.0)
private string name;
public string Name {
get { return name; }
protected set { name = value; }
}
or:
class BaseType {
private string name;
public BaseType(string name) {
this.name = name;
}
}
class DerivedType : BaseType {
public DerivedType() : base("Foo") {}
}
Philippe's suggestion to declare the fields as protected instead of private will indeed work - but I suggest you don't do it anyway.
Why should a derived class care about an implementation detail of how the data is stored? I suggest you expose protected properties which are (currently) backed by those fields, instead of exposing the fields themselves.
I treat the API you expose to derived classes as very similar to the API you expose to other types - it should be a higher level of abstraction than implementation details which you may want to change later.
You should declare them as "protected" instead of private
You are probably looking for a concept called constructor inheritance. You can forward arguments to the base classes constructor - see this example, where the Audi has a flag indicating whether it's an S-Line edition or not:
namespace ConstructorInheritance
{
abstract class Car
{
private int horsePower;
private int maximumSpeed;
public Car(int horsePower, int maximumSpeed)
{
this.horsePower = horsePower;
this.maximumSpeed = maximumSpeed;
}
}
class Audi : Car
{
private bool isSLineEdition = false;
// note, how the base constructor is called _and_ the S-Line variable is set in Audi's constructor!
public Audi(bool isSLineEdition, int horsePower, int maximumSpeed)
: base(horsePower, maximumSpeed)
{
this.isSLineEdition = isSLineEdition;
}
}
class Program
{
static void Main(string[] args)
{
Car car = new Audi(true, 210, 255);
// break here and watch the car instance in the debugger...
}
} }

Categories