Related
I'm learning OOP and trying to write a simple program that will execute some method every time when a specific varible will change.
I have two classes:
public class SomeClass {
private OtherClass object;
public OtherClass getObject() {
return this.object;
}
public void setObject(OtherClass object) {
objectChanged();
this.object = object;
}
private void objectChanged() {
System.out.println("Object has changed");
}
}
public class OtherClass {
private int value = 5;
public int getValue() {
return this.value;
}
public void setValue(int value) {
this.value = value;
}
}
The variable objectChanged should be called every time when variable "object" is changed. My first naive idea was to put the method call inside of set function. But what if you change the object after you set it? Like this:
SomeClass someObject = new SomeClass();
OtherClass otherObject = new OtherClass();
someObject.setObject(otherObject); //"Object has changed"
otherObject.setValue(10); //nothing happens yet
I need someObject to realize that object stored inside of it changed its value to 10, but how do i do it? Is it even possible in OOP?
It looks to be reasonable, but one should consider many things. This is why there is no automatic way to do it in general. It is not part of the OOP paradigm as such. If this would be some automatic behavior, it would cause huge overhead as it is not often needed to observe changes this way. But you can, of course, implement your way depending on your concrete requirements.
There are at least two approaches.
In MVVM (like WPF) there is an INotifyPropertyChanged interface (let's call it a pattern) you can use to trigger a notification yourself, mutch like you did with SomeClass. However when you are nesting objects, you need to wire up that mechanism.to cascade: you should do the same with OtherClass and also connect the actual instances to bubble up changes.
See: https://rehansaeed.com/tag/design-patterns/
An other option is the Observable pattern. Each time the object changes state, you emit an instance - the current instance. However, you should care to emit unmutable objects. At least by using an interface that makes it read-only. But you still need to wire up the object tree to react to the changes of nested objects.
If your platform supports reflection, and you create a proper toolset, you could make this wiring up quite simple. But again: this is not strictly related to the paradigm.
I created an automated property:
public int Foo { get; }
This is getter only.
But when I build a constructor, I can change the value:
public MyClass(string name)
{
Foo = 5;
}
Why is it possible, even though this is get-only?
This is a new C# 6 feature, "Getter-only auto-properties", also known as "Auto-Property Initializers for Read-Only Properties" as discussed in this MSDN magazine article 'C# : The New and Improved C# 6.0' by Mark Michaelis and in the C# 6.0 draft Language Specification.
The read-only field's setter is only accessible in the constructor, in all other scenarios the field is still read only and behaves as before.
This is a convenience syntax to reduce the amount of code you need to type and to remove the need to explicitly declare a private module level variable to hold the value.
This feature was seen as important as, since the introduction of Auto-Implemented Properties in C#3, mutable properties (those with a getter and setter) had become quicker to write than immutable ones (those with only a getter), meaning people were being tempted to use mutable properties to avoid having to type the code for a backing field usually required for read-only properties. There is more discussion of Auto-Implemented properties in the relevant section of the Microsoft C# Programming Guide.
This blog post, '#1,207 – C# 6.0 – Auto-Property Initializers for Read-Only Properties' by Sean Sexton Has a good explanation and example as follows:
Prior to C# 6.0, if you wanted a read-only (immutable) property, you’d
typically use a read-only backing field that is initialized in the
constructor, as shown below.
public class Dog
{
public string Name { get; set; }
// DogCreationTime is immutable
private readonly DateTime creTime;
public DateTime DogCreationTime
{
get { return creTime; }
}
public Dog(string name)
{
Name = name;
creTime = DateTime.Now;
}
}
In C# 6.0, you can use auto-implemented properties to implement a
read-only property. You do this by using an auto-property
initializer. The result is much cleaner than the above example, where
we had to explicitly declare a backing field.
public class Dog
{
public string Name { get; set; }
// DogCreationTime is immutable
public DateTime DogCreationTime { get; } = DateTime.Now;
public Dog(string name)
{
Name = name;
}
}
More details can also be found in the dotnet Roslyn repo on GitHub:
Auto-properties can now be declared without a setter.
The backing field of a getter-only auto-property is implicitly
declared as readonly (though this matters only for reflection
purposes). It can be initialized through an initializer on the
property as in the example above. Also, a getter-only property can be
assigned to in the declaring type’s constructor body, which causes the
value to be assigned directly to the underlying field:
This is about expressing types more concisely, but note that it also
removes an important difference in the language between mutable and
immutable types: auto-properties were a shorthand available only if
you were willing to make your class mutable, and so the temptation to
default to that was great. Now, with getter-only auto-properties, the
playing field has been leveled between mutable and immutable.
and in the C# 6.0 draft Language Specification (NB: The language specification is final as far as Microsoft are concerned, but it is yet to be approved as a EMCA/ISO standard, hence the 'draft'):
Automatically implemented properties
An automatically implemented property (or auto-property for short), is
a non-abstract non-extern property with semicolon-only accessor
bodies. Auto-properties must have a get accessor and can optionally
have a set accessor.
When a property is specified as an automatically implemented property,
a hidden backing field is automatically available for the property,
and the accessors are implemented to read from and write to that
backing field. If the auto-property has no set accessor, the backing
field is considered readonly (Readonly fields). Just like a readonly
field, a getter-only auto-property can also be assigned to in the body
of a constructor of the enclosing class. Such an assignment assigns
directly to the readonly backing field of the property.
An auto-property may optionally have a property_initializer, which is
applied directly to the backing field as a variable_initializer
(Variable initializers).
This is a new feature in C#6 that allows you to create read-only properties and initialize their values from the constructor (or inline when you declare them).
If you try to change the value of this property outside the constructor, it would give you a compile error.
It is read-only in the sense that once you initialize its value (inline or inside the constructor), you cannot change its value.
If it were not possible to initialize the read-only property from the constructor (or an auto-property initializer), then it would be useless, since it would always return the default value for its type (0 for numerics, null for reference types). The same semantics applied to readonly fields in all C# versions.
To define a true getter-only property (that cannot be initialized from the constructor), you need to specify what it returns as part of the definition:
public int Foo { get { return 5; } }
Or, more concisely in C# 6:
public int Foo => 5;
“readonly automatically implemented properties”
First of all I want to clarify that the property like
public string FirstName { get; }
Is known as “readonly automatically implemented properties”
To verify this you can run & check the above code with Visual Studio. If you change the language version from C#6.0 to C#5.0 then compiler will throw the following exception
Feature 'readonly automatically implemented properties' is not available in C# 5. Please use language version 6 or greater.
to change C# language version visit here
Now I am coming to your second question
“This is getter only. But when I build a constructor, I can change the value”
Microsoft introduces the “readonly automatically implemented properties” on the logic of read only. As we know that the keyword “readonly” is available from C#1.0. we use “readonly” keyword as modifier on a field and that field can be assigned in 2 ways either at the time of declaration or in a constructor in the same class.
In the same way value of “readonly automatically implemented properties” can be assigned in 2 ways
Way1 (at the time of declaration):
public string FirstName { get; } = "Banketeshvar";
Way2 (in a constructor in the same class)
Person()
{
FirstName = "Banketeshvar";
}
Purely ReadOnly Property
If you are looking for purely Readonly property then go for this
public string FullName => "Manish Sharma";
now you cannot assign value of “FullName” propery from constructor.
If you try to do that it will throw the following exceptions
“Property or indexer 'Person.FullName' cannot be assigned to -- it is read only”
Auto property feature was added to the language during C# 3.0 release. It allows you to define a property without any backing field, however you still need to use constructor to initialize these auto properties to non-default value. C# 6.0 introduces a new feature called auto property initializer which allows you to initialize these properties without a constructor like Below:
Previously, a constructor is required if you want to create objects
using an auto-property and initialize an auto-property to a
non-default value like below:
public class MyClass
{
public int Foo { get; }
public Foo(int foo)
{
Foo = foo;
}
}
Now in C# 6.0, the ability to use an initializer with the auto-property
means no explicit constructor code is required.
public string Foo { get; } = "SomeString";
public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };
You can find more information on this here
A variable declared readonly can be written within a constructor, but in languages which honor the attribute, cannot be modified after the constructor returns. That qualifier was provided as a language feature because it is often necessary for fields whose values will vary based upon constructor parameters (meaning they can't be initialized before the constructor starts) but won't have to change after constructors return, but it was only usable for variables exposed as fields. The semantics of readonly-qualified fields would in many cases have been perfect for public members except that it's often better for classes to expose members--even immutable ones--as properties rather than fields.
Just as read-write auto-properties exist to allow classes to expose mutable properties as easily as ordinary fields, read-only auto-properties exist to allow classes to expose immutable properties as easily as readonly-qualified fields. Just as readonly-qualified fields can be written in a constructor, so too with get-only properties.
I realize what the {get; set;} syntax is doing from this link on Auto-Implemented Properties.
What I do not understand is what is the point beside confusing the hell out of new C# programmers???
I mean first we get taught the whole point of Properties and Accessors is to prevent clients from having uncontrolled access to the fields within the class.
But isn't this EXACTLY with the auto-implemented property is doing?
I mean you can only use this syntax if you do not implement any logic for the property accessors. In fact you cannot even access the private anonymous backing field that is created by the compiler within the class object itself?
So what is the difference from just declaring a public field called Name in the class??
I see no difference between
class Foo
{
public string Name {get; set;}
}
and this
class Foo
{
public string Name;
}
Other then the fact that the auto-implemented property version is longer, more confusing, and made me spent 3 hours trying to understand it and gave me a splitting headache and made me want to write this rant!
Furthermore, it seems to me that the auto-implemented property version actually is less efficient in that the compiler is doing alot more work behind the scenes. It has to create the private anonymous backing filed, the get and set accessors, and finally call the accessors. Where the second version simply reads and writes to the public field directly.
It's just for simplification. The compiler will auto-generate the regular implementation.
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
I don't know why I started thinking about this, but now I can't seem to stop.
In C# - and probably a lot of other languages, I remember that Delphi used to let you do this too - it's legal to write this syntax:
class WeirdClass
{
private void Hello(string name)
{
Console.WriteLine("Hello, {0}!", name);
}
public string Name
{
set { Hello(name); }
}
}
In other words, the property has a setter but no getter, it's write-only.
I guess I can't think of any reason why this should be illegal, but I've never actually seen it in the wild, and I've seen some pretty brilliant/horrifying code in the wild. It seems like a code smell; it seems like the compiler should be giving me a warning:
CS83417: Property 'Name' appears to be completely useless and stupid. Bad programmer! Consider replacing with a method.
But maybe I just haven't been doing this long enough, or have been working in too narrow a field to see any examples of the effective use of such a construct.
Are there real-life examples of write-only properties that either cannot be replaced by straight method calls or would become less intuitive?
My first reaction to this question was: "What about the java.util.Random#setSeed method?"
I think that write-only properties are useful in several scenarios. For example, when you don't want to expose the internal representation (encapsulation), while allowing to change the state of the object. java.util.Random is a very good example of such design.
Code Analysis (aka FxCop) does give you a diagnostic:
CA1044 : Microsoft.Design : Because
property 'WeirdClass.Name' is write-only,
either add a property getter with an
accessibility that is greater than or
equal to its setter or convert this
property into a method.
Write-only properties are actually quite useful, and I use them frequently. It's all about encapsulation -- restricting access to an object's components. You often need to provide one or more components to a class that it needs to use internally, but there's no reason to make them accessible to other classes. Doing so just makes your class more confusing ("do I use this getter or this method?"), and more likely that your class can be tampered with or have its real purpose bypassed.
See "Why getter and setter methods are evil" for an interesting discussion of this. I'm not quite as hardcore about it as the writer of the article, but I think it's a good thing to think about. I typically do use setters but rarely use getters.
I have code similar to the following in an XNA project. As you can see, Scale is write-only, it is useful and (reasonably) intuitive and a read property (get) would not make sense for it. Sure it could be replaced with a method, but I like the syntax.
public class MyGraphicalObject
{
public double ScaleX { get; set; }
public double ScaleY { get; set; }
public double ScaleZ { get; set; }
public double Scale { set { ScaleX = ScaleY = ScaleZ = value; } }
// more...
}
One use for a write-only property is to support setter dependency injection, which is typically used for optional parameters.
Let's say I had a class:
public class WhizbangService {
public WhizbangProvider Provider { set; private get; }
}
The WhizbangProvider is not intended to be accessed by the outside world. I'd never want to interact with service.Provider, it's too complex. I need a class like WhizbangService to act as a facade. Yet with the setter, I can do something like this:
service.Provider = new FireworksShow();
service.Start();
And the service starts a fireworks display. Or maybe you'd rather see a water and light show:
service.Stop();
service.Provider = new FountainDisplay(new StringOfLights(), 20, UnitOfTime.Seconds);
service.Start();
And so on....
This becomes especially useful if the property is defined in a base class. If you chose construction injection for this property, you'd need to write a constructor overload in any derived class.
public abstract class DisplayService {
public WhizbangProvider Provider { set; private get; }
}
public class WhizbangService : DisplayService { }
Here, the alternative with constructor injection is:
public abstract class DisplayService {
public WhizbangProvider Provider;
protected DisplayService(WhizbangProvider provider) {
Provider = provider ?? new DefaultProvider();
}
}
public class WhizbangService : DisplayService {
public WhizbangService(WhizbangProvider provider)
: base(provider)
{ }
}
This approach is messier in my opinion, because you need to some of the internal workings of the class, specifically, that if you pass null to the constructor, you'll get a reasonable default.
In MVP pattern it is common to write a property with a setter on the view (no need for a getter) - whenever the presenter sets it content the property will use that value to update some UI element.
See here for a small demonstration:
public partial class ShowMeTheTime : Page, ICurrentTimeView
{
protected void Page_Load(object sender, EventArgs e)
{
CurrentTimePresenter presenter = new CurrentTimePresenter(this);
presenter.InitView();
}
public DateTime CurrentTime
{
set { lblCurrentTime.Text = value.ToString(); }
}
}
The presenter InitView method simply sets the property's value:
public void InitView()
{
view.CurrentTime = DateTime.Now;
}
Making something write-only is usefulwhenever you're not supposed to read what you write.
For example, when drawing things onto the screen (this is precisely what the Desktop Window Manager does in Windows):
You can certainly draw to a screen, but you should never need to read back the data (let alone expect to get the same design as before).
Now, whether write-only properties are useful (as opposed to methods), I'm not sure how often they're used. I suppose you could imagine a situation with a "BackgroundColor" property, where writing to it sets the background color of the screen, but reading makes no sense (necessarily).
So I'm not sure about that part, but in general I just wanted to point out that there are use cases for situations in which you only write data, and never read it.
Although the .NET design guidelines recommend using a method ("SetMyWriteOnlyParameter") instead of a write-only property, I find write-only properties useful when creating linked objects from a serialised representation (from a database).
Our application represents oil-field production systems. We have the system as a whole (the "Model" object) and various Reservoir, Well, Node, Group etc objects.
The Model is created and read from database first - the other objects need to know which Model they belong to. However, the Model needs to know which lower object represents the Sales total. It makes sense for this information to be stored a Model property. If we do not want to have to do two reads of Model information, we need to be able to read the name of Sales object before its creation. Then, subsequently, we set the "SalesObject" variable to point to the actual object (so that, e.g., any change by the user of the name of this object does not cause problems)
We prefer to use a write-only property - 'SalesObjectName = "TopNode"' - rather than a method - 'SetSalesObjectName("TopNode") - because it seems to us that the latter suggests that the SalesObject exists.
This is a minor point, but enough to make us want to use a Write-Only property.
As far as I'm concerned, they don't. Every time I've used a write-only property as a quick hack I have later come to regret it. Usually I end up with a constructor or a full property.
Of course I'm trying to prove a negative, so maybe there is something I'm missing.
I can't stop thinking about this, either. I have a use case for a "write-only" property. I can't see good way out of it.
I want to construct a C# attribute that derives from AuthorizeAttribute for an ASP.NET MVC app. I have a service (say, IStore) that returns information that helps decide if the current user should be authorized. Constructor Injection won't work, becuase
public AllowedAttribute: AuthorizeAttribute
{
public AllowedAttribute(IStore store) {...}
private IStore Store { get; set; }
...
}
makes store a positional attribute parameter, but IStore is not a valid attribute parameter type, and the compiler won't build code that is annotated with it. I am forced to fall back on Property Setter Injection.
public AllowedAttribute: AuthorizeAttribute
{
[Inject] public IStore Store { private get; set; }
...
}
Along with all the other bad things about Property Setter instead of Constructor Injection, the service is a write-only property. Bad enough that I have to expose the setter to clients that shouldn't need to know about the implementation detail. It wouldn't do anybody any favors to let clients see the getter, too.
I think that the benefit of Dependency Injection trumps the guidelines against write-only properties for this scenario, unless I am missing something.
I just came across that situation when writing a program that reads data from a JSON database (Firebase). It uses Newtonsoft's Json.NET to populate the objects. The data are read-only, i.e., once loaded they won't change. Also, the objects are only deserialized and won't be serialized again. There may be better ways, but this solution just looks reasonable for me.
using Newtonsoft.Json;
// ...
public class SomeDatabaseClass
{
// JSON object contains a date-time field as string
[JsonProperty("expiration")]
public string ExpirationString
{
set
{
// Needs a custom parser to handle special date-time formats
Expiration = Resources.CustomParseDateTime(value);
}
}
// But this is what the program will effectively use.
// DateTime.MaxValue is just a default value
[JsonIgnore]
public DateTime Expiration { get; private set; } = DateTime.MaxValue;
// ...
}
No, I can' imagine any case where they can't be replaced, though there might people who consider them to be more readable.
Hypothetical case:
CommunicationDevice.Response = "Hello, World"
instead of
CommunicationDevice.SendResponse("Hello, World")
The major job would be to perform IO side-effects or validation.
Interestingly, VB .NET even got it's own keyword for this weird kind of property ;)
Public WriteOnly Property Foo() As Integer
Set(value As Integer)
' ... '
End Set
End Property
even though many "write-only" properties from outside actually have a private getter.
I recently worked on an application that handled passwords. (Note that I'm not claiming that the following is a good idea; I'm just describing what I did.)
I had a class, HashingPassword, which contained a password. The constructor took a password as an argument and stored it in a private attribute. Given one of these objects, you could either acquire a salted hash for the password, or check the password against a given salted hash. There was, of course, no way to retrieve the password from a HashingPassword object.
So then I had some other object, I don't remember what it was; let's pretend it was a password-protected banana. The Banana class had a set-only property called Password, which created a HashingPassword from the given value and stored it in a private attribute of Banana. Since the password attribute of HashingPassword was private, there was no way to write a getter for this property.
So why did I have a set-only property called Password instead of a method called SetPassword? Because it made sense. The effect was, in fact, to set the password of the Banana, and if I wanted to set the password of a Banana object, I would expect to do that by setting a property, not by calling a method.
Using a method called SetPassword wouldn't have had any major disadvantages. But I don't see any significant advantages, either.
I know this has been here for a long time, but I came across it and have a valid (imho) use-case:
When you post parameters to a webapi call from ajax, you can simply try to fill out the parameters class' properties and include validation or whatsoever.
public int MyFancyWepapiMethod([FromBody]CallParams p) {
return p.MyIntPropertyForAjax.HasValue ? p.MyIntPropertyForAjax.Value : 42;
}
public class CallParams
{
public int? MyIntPropertyForAjax;
public object TryMyIntPropertyForAjax
{
set
{
try { MyIntPropertyForAjax = Convert.ToInt32(value); }
catch { MyIntPropertyForAjax = null; }
}
}
}
On JavaScript side you can simply fill out the parameters including validation:
var callparameter = {
TryMyIntPropertyForAjax = 23
}
which is safe in this example, but if you handle userinput it might be not sure that you have a valid intvalue or something similar.
For example, do you use accessors and mutators within your method definitions or just access the data directly? Sometimes, all the time or when in Rome?
Always try to use accessors, even inside the class. The only time you would want to access state directly and not through the public interface is if for some reason you needed to bypass the validation or other logic contained in the accessor method.
Now if you find yourself in the situation where you do need to bypass that logic you ought to step back and ask yourself whether or not this need betrays a flaw in your design.
Edit: Read Automatic vs Explicit Properties by Eric Lippert in which he delves into this very issue and explains things very clearly. It is about C# specifically but the OOP theory is universal and solid.
Here is an excerpt:
If the reason that motivated the
change from automatically implemented
property to explicitly implemented
property was to change the semantics
of the property then you should
evaluate whether the desired semantics
when accessing the property from
within the class are identical to or
different from the desired semantics
when accessing the property from
outside the class.
If the result of that investigation is
“from within the class, the desired
semantics of accessing this property
are different from the desired
semantics of accessing the property
from the outside”, then your edit has
introduced a bug. You should fix the
bug. If they are the same, then your
edit has not introduced a bug; keep
the implementation the same.
In general, I prefer accessors/mutators. That way, I can change the internal implementation of a class, while the class functions in the same way to an external user (or preexisting code that I dont want to break).
The accessors are designed so that you can add property specific logic. Such as
int Degrees
{
set
{
_degrees = value % 360;
}
}
So, you would always want to access that field through the getter and setter, and that way you can always be certain that the value will never get greater than 360.
If, as Andrew mentioned, you need to skip the validation, then it's quite possible that there is a flaw in the design of the function, or in the design of the validation.
Accessors and Mutators are designed to ensure consistency of your data, so even within your class you should always strive to make sure that there's no possible way of injecting unvalidated data into those fields.
EDIT
See this question as well:
OO Design: Do you use public properties or private fields internally?
I don't tend to share with the outside world the 'innards' of my classes and so my internal needs for data (the private method stuff) tends to not do the same sort of stuff that my public interface does, typically.
It is pretty uncommon that I'll write an accessor/mutator that a private method will call, but I suspect I'm in the minority here. Maybe I should do more of this, but I don't tend to.
Anyway, that's my [patina covered] two cents.
I will often start with private auto properties, then refactor if necessary. I'll refactor to a property with a backing field, then replace the backing field with the "real" store, for instance Session or ViewState for an ASP.NET application.
From:
private int[] Property { get; set; }
to
private int[] _property;
private int[] Property
{
get { return _property; }
set { _property = value; }
}
to
private int[] _property;
private int[] Property
{
get
{
if (_property == null)
{
_property = new int[8];
}
return _property;
}
set { _property = value; }
}
to
private int[] Property
{
get
{
if (ViewState["PropertyKey"] == null)
{
ViewState["PropertyKey"] = new int[8];
}
return (int[]) ViewState["PropertyKey"];
}
set { ViewState["PropertyKey"] = value; }
}
Of course, I use ReSharper, so this takes less time to do than to post about.