Reputation: 193302
Is there some internal difference between the C# syntactic sugar way of making properties:
public string FirstName { get; set; }
and just making public variables like this:
public string LastName;
I assume the first way is preferred and the second to be avoided. However, I often see this type of readonly property being used which is a form of the second type above:
public readonly string InternalCode;
Is this a best-practice way to create readonly property?
using System;
namespace TestProps
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
customer.FirstName = "Jim";
customer.LastName = "Smith";
customer.Show();
}
}
class Customer
{
public string FirstName { get; set; } //prefered
public string LastName; //avoid
public readonly string InternalCode; //???
public Customer()
{
InternalCode = "234729834723984";
}
public void Show()
{
Console.WriteLine("{0}, {1} ({2})", LastName, FirstName, InternalCode);
Console.ReadLine();
}
}
}
Upvotes: 19
Views: 10587
Reputation: 309
Short answer: public const is ok, public readonly not necessarily, public get without set not neccessarily. Objects that cannot be changed without being assigned can be ok. Reference types are dangerous as you can still change their values, even if you cannot change the reference itself.
The problem with the readonly keyword is that it does not mean what you'd understand as logically readonly/immutable. It means more like "can only be assigned in constructor". References cannot be changed, but its values can. There is no "real" readonly keyword provided by c#, unfortunately. See also https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/
Properties cannot have the readonly keyword (https://titombo.wordpress.com/2012/11/11/using-the-c-modifiers/). As others noted, you can use a property and only define get and no set, though you cannot set that property in the constructor. Using a private set, you can set the property from annywhere in the class, not only in the constructor. The readonly field would be a little more restrictive.
Upvotes: 0
Reputation: 3414
Using a property provides an interface which is more resistant to change in the future. Let's say some time in the future, a decision is made to add a prefix to the internal code.
Using a public readonly variable exposes your internal structure and you will have a hard time adding the prefix to every line you used the internal variable of the class.
Using a Property, you can just write the following
public string InternalCode {
get { return _prefix + _internalCode; }
}
and you're done!
Upvotes: 4
Reputation: 176169
Since he didn't answer (yet) and no one else referenced this yet: There is a great article on this topic by Jon Skeet amending his book C# in depth (give credits to Jon):
Upvotes: 17
Reputation: 4518
In my opinion, it's ok to expose public fields (especially if they're readonly or const). Having said that, I'd say that in the example you're presenting, I'd probably go with properties since they'll give you 2 advantages (over fields): 1) better encapsulation and may let you adapt your code in the future and 2) if you're doing data binding, then you do need the properties.
Upvotes: 3
Reputation: 33476
Yes. it is OK to have a public readonly variables (it is just that they can be initialized at the time of definition or constructor).
e.g. Decimal.MaxValue
Having public readonly property is good, if the backing value changes (other than what it was initialized with).
e.g. Environment.TickCount
I thought that Environment.NewLine will be a public readonly variable. Well, it is a public property (get only) and the reason could be to maintain compatibility across different platform.
Upvotes: 1