C# basic property understanding - c#

I am learning C# and i have encounter the following piece of code
public class Album
{
public virtual int AlbumId { get; set; }
public virtual int GenreId { get; set; }
public virtual int ArtistId { get; set; }
public virtual string Title { get; set; }
public virtual decimal Price { get; set; }
public virtual string AlbumArtUrl { get; set; }
public virtual Genre Genre { get; set; }
public virtual Artist Artist { get; set; }
}
just wondering what's the different with the following? i mean without the get and set you can access those public property as well. what's make it important to have those get and set?
public class Album
{
public virtual int AlbumId;
public virtual int GenreId;
public virtual int ArtistId;
public virtual string Title;
public virtual decimal Price;
public virtual string AlbumArtUrl;
public virtual Genre Genre;
public virtual Artist Artist;
}

To have control over your object private fields values. for example if you don't wanna allow nulls or negative values for integers.
bool started;
public bool Started
{
get { return started; }
set
{
started = value;
if (started)
OnStarted(EventArgs.Empty);
}
}
another example
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
set {
if (value < 0)
positiveNumber = 0;
else positiveNumber = value;
}
}
and also another implementation of read only properties could be as follows
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
}

You can't declare a virtual field
public class Album
{
public virtual int AlbumId; // <- Syntax error
...
}
properties are, in fact, methods: get or(and) set, so
public class Album
{
public virtual int AlbumId { get; set; } // <- Both get and set methods declared as virtual ones
...
}
And you can override these get's or(and) set's in derived class if you want:
public class GreatAlbum: Album {
private Boolean m_IsGreat;
public override int AlbumId {
get {
if (m_IsGreat)
return base.AlbumId
else
return 0;
}
set {
m_IsGreat = (value != 0);
base.AlbumId = value;
}
}
...
}

With providing get(accessor) and set(mutator) methods, you can control accessing and mutating.
For example:
You have a property that you don't want to be set any value more than 15. So u make required restrictions in your set method. Unless that set method, you can't control.
But in your example, your get and set methods are default, means controlling nothing.

The main reason behind properties is to protecting and presenting private data in a controlled way.
In fact, properties show their abilties in the usage like this:
public virtual int AlbumId
{
get { // ... some magical operations ... }
set { // ... some magical operations ... }
}
And about your main question - what's the difference in this example - the main point to attention is the virtual keyword.
This keyword causes the property to be overrideable, So any other code could override the default get; method. It meens that you have the default behavior for yourself, and other codes (Extremely used in Entity Framework) implement their own logic!
Those second ones in your example aren't properties, so they don't express this magical ability...!

In the first case you are dealing with properties, in the second with fields.
Using fields has several drawbacks when compared to using properties. These drawbacks include:
You can set a breakpoint in a get or set of a property, but you can not set a breakpoint on access to the field.
Making fields public violates the information hiding principle.
The binary MSIL code for accessing fields and properties is different, so if you change a public field to a public property in the future, although the source code stays compatible, any dependant binary code breaks.
The code required to use reflection is different, hence when you move from a field to a property, your reflection code will break.
To cut a long story short: Always use public properties, NEVER use public fields.

There are a number of differences:
Properties are turned into methods by the compiler. As such, you can declare them virtual and override them in a derived class.
Using properties, you can put logic in the getter or setter (filtering, validation etc).
When you use automatically implemented properties ({ get;set;}), it may seem that you might as well just use public fields. However, using properties means you can change your getter or setter implementation at a later time, without changing the interface your class is exposing. If you had used a field and wanted to implement filtering whenever that field was read, you would have to introduce a new method, make the field private and break all existing consumers of the type.
Personally, I think the automatically implemented properties promote bad style, because they do not encourage encapsulation. Tools like ReSharper also like to generate properties with {get;set} accessors. Novice developers thus typically end up with classes with lots of {get;set;} properties exposing the type's state to the world. You should at least use {get; private set;} by default.

Related

What is the purpose of set { return; }?

I've seen the following code in various places:
namespace My.name.space
{
class myClass
{
public CustomObject Name
{
get { return new CustomObject (this.Dog); }
set { return; }
}
}
}
What is the purpose of set { return; }?
I don't understand what purpose set return would serve.
I would think you could just remove the set accessor completely.
None. It's somebody who doesn't quite know that a read-only property can be expressed much more simply by not including the set
public Derp MuhDerp { get { return _derp; } }
Interesting point brought up by CSharpie in a comment...
If you have to have a set because it is defined in an interface, you can add the set but omit the return:
public Derp MuhDerp { get { return _derp; } set { } }
Of course, if the interface defines a setter, you should probably make sure it works as expected :)
It is basically to give the illusion that there is a setter, well there is, but does nothing. But it was probably done to keep some interface happy or a parent class:
public CustomObject Name
{
get { return new CustomObject( this.Dog ); }
set { return; } // does absolutely nothing
}
Here is a class:
public abstract class A {
public abstract void DoWork();
public abstract string SomeProperty { get; set; }
}
Here is giving the illusion that it is implementing the abstract interface, but it really is not implementing everything:
public class B : A {
public override string SomeProperty
{
get
{
return "whatever";
}
set
{
return; // keep interface happy
}
}
public override void DoWork() {
// I am not doing nothing but compiler is happy
}
}
That code also breaks Liskov Substitution Principle.
That simply means "don't do anything, I don't want to make an assignment". It's like a no-op in the setter. It's also equivalent to an empty setter, i.e. set { }. It's a matter of preference, really; some people prefer not to have empty code bodies, I guess.
Of course, you wouldn't typically do it that way (as Will points out). You would just use a read-only property, but there is a key difference: when using a read-only property, an attempt to set it will fail at compile time; if you're using the one you asked about, then it won't fail at all, it will simply "do nothing" at runtime.
Which one you use largely depends on what you want your application to do. I'll point out that using this approach (rather than a read-only property) can lead to brittle code, as the programmer may not be aware that their deliberate attempt to assign a value is being ignored.
Properties in C# are just syntax candy for a special case of methods.
A "regular" property like
public int Foo {get;set;}
is actually (sommething similiar)
int _foo;
public int get_Foo() { return _foo;}
public void set_Foo(int value) { _foo = value;}
However you are allowed to speficy yourself, what happens in the setter and getter
public int Foo { get { return 47; } set { Console.WriteLine(value); } }
So taking your example the compiler will turn it into
public CustomObject get_Name() { return new CustomObject (this.Dog); }
public void set_Name(CustomObject value) { return; }
Which does nothing in the set-Method at all. So why would someone do this?
There are a few reasons that make sense:
They want to later introduce functionality to that setter, so it serves as a placeholder for now
The setter is required, because the Property comes from an interface, yet it makes no sense to set the value in that concrete implementation
Some API or stuff based on reflection requires a set-method even if it is not used.
this is the same as a read only property, but the property can be setted (obviously with no sense).
There are some great answers here (and I know this is an old question), but I wanted to provide some additional context for what this is, when it might be useful, and how I've used it in production code.
First, the answer: This is normally not useful. Just define a readonly property. As others have said, you're completely right that you could remove the set and have almost the same effect -- except that the property could no longer be assigned to.
Now, here's where this can be useful. For a lot of the smaller microservices I write, I use Azure Tables for storage. This is a key-value database, where your key comes in two parts: a PartitionKey and a RowKey. They're pretty self-explanatory.
Generally I'll end up with a couple of small tables (such as ones holding basic application-managed settings) that don't make sense to use a PartitionKey with -- i.e. they only have one identifying piece of information, such as an id, along with a value.
The Azure.Data.Tables library is really nice, and provides an interface to implement for your DTOs. Implementing this interface would normally look like the following:
using Azure;
using Azure.Data.Tables;
namespace SmartsheetIntegration.Qar.DataStores.Models;
public class MyDto : ITableEntity
{
public MyDto() {}
public MyDto(string partitionKey, string rowKey)
{
PartitionKey = partitionKey;
RowKey = rowKey;
}
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public ETag ETag { get; set; }
}
Now, what about these simple app settings? I want to make sure that they never end up with a PartitionKey, because I need to know for sure that if I want to retrieve all of them, I can query for 'PartitionKey = ""' and get everything back.
The simple solution to this is:
using Azure;
using Azure.Data.Tables;
namespace SmartsheetIntegration.Qar.DataStores.Models;
public class MyDto : ITableEntity
{
public MyDto() {}
public MyDto(string partitionKey, string rowKey)
{
PartitionKey = partitionKey;
RowKey = rowKey;
}
public string PartitionKey
{
get => "";
set { } // the same as set { return; }
}
public string RowKey { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public ETag ETag { get; set; }
}
Now Azure Tables can do whatever it wants in its library, but I can guarantee that the PartitionKey saved to the database will always be an empty string.
So yes, the number of situations where this is useful isn't huge -- but there are interface implementations where it makes sense.

What difference does this `private set` make within this immutable class

I'm studying this simple class and wondering what difference the private set of the Name property actually makes?
If that line simply read public string Name { get; } how would the user's interaction with the class change?
public class Contact2
{
// Read-only properties.
public string Name { get; private set; }
public string Address { get; }
// Private constructor.
private Contact2(string contactName, string contactAddress)
{
Name = contactName;
Address = contactAddress;
}
// Public factory method.
public static Contact2 CreateContact(string name, string address)
{
return new Contact2(name, address);
}
}
They are both read-only properties, and objects of this class can only be constructed via the static method, so does it matter if the set of name is private or not?
EDIT
It is part of this MSDN code:
https://msdn.microsoft.com/en-us/library/bb383979.aspx
In C# 6:
public string Name { get; private set; }
Can be set from any method within the class.
public string Address { get; }
Is a read-only property and can only (and must) be set on initialization.
In your code they're functioning the same way, however the read-only property enforces an additional constraint making the property immutable as it can only be set once, whereas you could add a method to the class which mutates Name making the class mutable.
Getter-only auto properties like public string Name { get; } were not allowed before C# 6.0, so the code would not compile. That's why you needed a private setter before.
See: Getter-only auto-properties.

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;
}
}

decorating classes with properties to avoid duplication

I am trying to work out the best way to approach the following ..
i need to pass AvailabilityOption/LimitedAvailabilityOption types to - well a service as it happens, and then get back BookingOption types.
I have routines which will generate the availability types, but am unsure if i need to go through each of my Option objects effectively duplicating versions of them inheriting from BookingOption and AvailabilityOption in turn. or can I do some sort of 'Decoration' of the simple options with the availability classes and then cast them back down to booking ones when i pass them back again.
I know there is a decoration pattern but having read a bit about this it appears that it is more about decorating at runtime.. I may well be misunderstanding.
I suspect I havent explained this very well but here is some code..
EDIT: effectively the option is a base for a number of possible options on a booking - such as an excursion or some other extra, of which there are quite afew. the availability extends that to determine what space there is on any option, but it is just extending the option itself, with the price and possibly the numbers already booked on that option.
the BookingOption is there to be returned from the routine that effectively chooses from the options based on their price and availability. I am just trying to return the bare minimum at the booking point, which is really the date when the option is required and which option it is. the availability at this point is moot..
public abstract class Option{
public int OptionID { get; set; }
public OptionType OptionType { get; set; }
public string EqtCode { get; set; }
public string CentreCode { get; set; }
public virtual string Description { get; set; }
}
public abstract BookingOption : Option{
public DateTime WeekStartDate{get;set;}
}
public abstract class AvailabilityOption : BookingOption {
public decimal Price{get;set;}
public override string Description{
get{return string.format("{0} # {1}", base.Description, Price.ToString());
set{ base.Description = value;}
}
}
public abstract class LimitedAvailabilityOption : AvailabilityOption{
public int MinNumber { get; set; }
public int MaxNumber { get; set; }
public int TotalBooked { get; set; }
public int TotalRemaining { get; set; }
public override string Description
{
get
{
return string.Format("{0} ({1} # {2})",
base.Description, TotalRemaining.ToString(), Price.ToString());
}
set { base.Description = value;}
}
}
public class Option1 : Option{
public Option1(){}
}
public class Option2 : Option{
public Option2(){}
}
public List<BookingOption> BookWithAvail(List<AvailabiliyOption> options){
//pick options based on avail and pass back the booking versions so write away...
}
It looks like answer depends on how you plan to use Availability and Limited availabilitty qualities of essences. If those availability-qualities are only applicable to LimitedAvailabilityOption and AvailabilityOption classes - than it does not seems there is a big need of implementation Availability or LimitedAvailability in separate classes, as each of those classes will be used to distinguish only one kind of other essences (LimitedAvailabilityOption and AvailabilityOption respectively). It would make sense to use decoration pattern and implement classes for Availability and Limited availability qualities only if you plan assign each of them to multiple essences that are not connected with inheritance relationship (including inheritance through intermediate classes). And if you plan to spread usage of availability-qualities across multiple classes that are not supposed to have any inheritance connection via common ancestor that has availability property - then the only choice is to extract those availability qualities into separate classes.

Downcast on POCO classes

I have a group of POCO classes:
class ReportBase
{
public string Name { get; set; }
public int CustomerID { get; set; }
}
class PurchaseReport : ReportBase
{
public int NumberOfPurchases { get; set; }
public double TotalPurchases { get; set; }
public bool IsVip { get; set; }
}
class SaleReport : ReportBase
{
public int NumberOfSales { get; set; }
public double TotalSales { get; set; }
}
I have a web method to return ReportBase. The caller uses the return value to update UI(WPF) based on the actually type by downcasting and checking the type (one grid for sale and one for purchase). Someone suggested to use three web methods and each return the specific type.
I understand that downcast is in general against design principle by introducing if/else. Instead we should use virtual functions. But in POCO class, we don't really have virtual behaviors (only extra fields).
Are you for or against downcast in this case, why?
IMO it's all about intention. Returning just the base class doesn't say anything, especially as you return it only to save some key strokes. As a developer what do you prefer?
ReportBase GetReport() // if type==x downcast.
//or
PurchaseReport GetPurchaseReport()
SaleReport GetSalesReport()
What approach would you want to use to make the code more maintainable? Checking type and downcasting is an implementation detail after all and you probably have a method like this
public void AssignReport(ReportBase report)
{
//check, cast and dispatch to the suitable UI
}
What's wrong with this? It's lacking transparency, and this method should always know about what reports are needed by what UI elements. Any time you add/remove an element you have to modify this method too.
I think is much clear and maintainable something like this
salesGrid.DataSource=repository.GetSalesReport();
purchaseGrid.DataSource=repository.GetPurchaseReport();
than this
var report=repository.GetReport();
AssignReport(report); //all UI elements have their data assigned here or only 2 grids?
So I think that, POCO or not, I will favour the three web methods approach.

Categories