Pretty simple question, say I have a class with 20 reference type properties that I know will only be set at class creation/immediately after class is created and where none of the properties are really mandatory.
In this scenario, would best practice be to create a ctor accepting 20 properties (which, since they are all reference types, would still allow you to pass null if you wanted to) and to ensure none of my properties have a setter
or ...
To simply not have a ctor at all and just provide a setter for all of my properties?
I am leaning towards the latter because of ease of implementation and (arguably) cleaner code even though that doesn't guarantee object immutability, but again these classes are only used internally and I know that I won't be changing them anyway.
EDIT
If you're going to vote to close the question, at least have the decency of explaining why you think the question is not "good enough" for the ohh-so-high SO standards.
If this is not a question that belongs here, I really don't know what SO is for anymore.
If all these properties aren't mandatory and they don't have to be readonly, you don't need a constructor. No one wants to call a constructor that takes 20 arguments, especially if they aren't necessary.
So even if this question tends to be subjective, use properties and omit the constructor.
You should make them properties and use an object initializer:
class Cat
{
// Auto-implemented properties.
public int Age { get; set; }
public string Name { get; set; }
public object OtherProperty { get; set; }
}
Cat cat = new Cat { Age = 10, Name = "Fluffy" };
This gives you nice compact code, without having to specify the properties you don't need. Even if you do specify all the properties, it's not much longer.
I'd use a constructor where properties are mandatory, or based on some sort of source object like a DataRow or file.
It looks like Single Responsibility Principle violation. It's recommended to have 0-3 parameters in method including constructor.
Related
What is the difference in functionality between using a field with get and set methods versus using a property to attribute a value to an object through a class? For example, when setting up a value val in a class, are there any reasons to choose one of the two classes below over the other (other than length of code written and interface compatibility):
class FieldTest
{
public FieldTest()
{
}
private string val;
public void SetVal(string temp)
{
val = temp;
}
public string GetVal()
{
return val;
}
}
Versus
class PropertyTest
{
public PropertyTest()
{
}
public string val { get; set; }
}
Tested Usage in Visual Studio 2010:
class TestFunctions
{
static void Main(string[] args)
{
FieldTest Test_Fields = new FieldTest();
Test_Fields.SetVal("Test");
string temp_str = Test_Fields.GetVal();
PropertyTest Test_Property = new PropertyTest();
Test_Property.val = "test";
string temp_str_prop = Test_Property.val;
System.Windows.Forms.MessageBox.Show("Field: " + temp_str + "\n\nProperty: " + temp_str_prop);
}
}
I know only a field can use ref and out keywords, but the other advantages usually attributed to a property--encapsulation, versioning, etc-- seem to be the same with these two setups.
I've checked articles such as Difference between Property and Field in C# 3.0+ and What is the difference between a Field and a Property in C#?. Though they give good descriptions of the ideas behind properties and fields, I have not been able to find a specific answer to my question.
Thanks in advance for clarification.
EDIT 2015-07-29:
I believe this to be a separate question from other StackOverflow answers, such as those found here, as these answers did not seem to specifically address using fields with their own get and set methods as a replacement for a property.
My statement above, "I know only a field can use ref and out keywords..." comes from answers similar to the following (found here):
"Fields may be used for out / ref parameters, properties may not. Properties support additional
logic – this could be used to implement lazy loading among other things."
The functionality is almost identical. For "normal" code use-cases, these snippets will act exactly the same, as a property is in effect just a hidden field with two hidden methods (get and set).
However, there is a difference when it comes to reflection. Properties show up as PropertyInfo, and methods MethodInfo. You also can only bind to properties (in WPF/WinRT). Serialization also only works against properties. Both of these (and doubtlessly others) fail because they use reflection to find the members to act against.
So depending on your use case, they are the same. Generally speaking, I would stick with properties.
In the .NET world properties are how you attribute data to objects. Methods are typically actions associated with the objects. Fields usually store internal (private) object instance state.
Under the hood, read/write property accessors get compiled to get and set methods.
Additionally, many technologies do not work with methods. Data Annotations, Entity Framework, and serialization are a few that pop instantly to mind.
I would always vote for properties rather than getter and setter.
First of all - using Property is neat and clean. The code is more clear, less junky and easy to understand.
If you use Automatic Property you just need one line of code for one Property where you need at least 6 for a getter and setter approach. So if your class has 20 attributes then total 120 lines of codes? Oh Man!!!
but the other advantages usually attributed to a property--encapsulation, versioning, etc-- seem to be the same with these two setups. => I disagree, consider a scenario where you want to force all implementation of an interface with an attribute to be readonly. That is easily doable with a readonly property in the interface. Now try that with getter and setter. Frankly you can't.
Then there comes Serialization. You cannot serialize a computed value unless that is a property. Methods are never serialized.
Let's take a look at your second code:
class PropertyTest
{
public PropertyTest()
{
}
public string val { get; set; }
}
As said in the Auto-Implemented Properties page on MSDN, when you declare an auto-implemented property like in your example, the compiler creates a private, anonymous backing field that can only be accessed through the property's get and set accessors.
In other words, it would be like writing this code:
public class PropertyTest
{
public PropertyTest()
{
}
private string _val;
public string val
{
get { return _val; }
set { val = value; }
}
}
So, properties are a way to encapsulate fields. As you can see on MSDN, too:
A property is a member that provides a flexible mechanism to read,
write, or compute the value of a private field. Properties can be used
as if they are public data members, but they are actually special
methods called accessors. This enables data to be accessed easily and
still helps promote the safety and flexibility of methods.
In my opinion, you should always prefer to use the property implementation than the getter/setter methods. Not because it seems cleaner and flexible to make things like compute values, but it is actually easier to implement (you write less code on auto-implemented properties).
We could say that there are almost no difference from the properties than the getter/setter methods too, if we look at the part where MSDN says "but they are actually special methods called accessors". But again, we have the example of brainless coder above, we have Framework behaviours that encourages us to use properties: methods can not be serialized, while properties can.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between a field and a property in C#
I'm a beginning programmer and I've read all about class properties. Books state that properties allow you to indirectly access member variables. Ok, so what makes it any different than just making the field public and accessing it directly?
Here's a quote from Learning C# 3.0 by Jesse Liberty:
For example, you might want external
classes to be able to read a value, but not change it; or you might want to write
some code so that the internal field can accept only values in a certain range. If you
grant external classes free access to your member fields, you can’t control any of that.
I don't understand what he is saying here. Can someone further explain this or give an example of why I would want to use a property over making the field public. As I understand it now they would both accomplish the same exact thing...so I'm obviously missing something here.
The other answers provided so far provide details of the advantages of accessor/mutator logic, but all seem to miss out on the ideological point about object encapsulation.
You see, class member fields are an implementation detail. If you have a class that represents a collection, for example, then you could implement it as a linked list (and expose the root-node via a public field) or you could implement it as a resizable array and expose the index0 member.
The problem with revealing implementation details is that you lose any kind of defined interface between your class and its consumers. By ensuring all operations are done via defined methods (controlled by the class itself) you make it easier to work with and provide for a long-term viewpoint. For example, you are far more easily able to convert your collection implementation from one type (the linked-list) to another (the array) without breaking any contracts with your class' consumers.
Don't worry about any performance impact of trivial accessor/mutator methods: the JIT compiler will inline the property methods. If you'll run some benchmarks you'll see the performance of properties vs fields is identical.
He's saying that properties can provide a getter but not a setter, therefore making them read-only (for example)
Properties are just syntactic sugar for a method e.g.
public int SomeProperty { get; set; }
is just sugar for
private int _someProperty;
public int SomeProperty_get()
{
return _someProperty;
}
public void SomeProperty_set(int value)
{
_someProperty = value;
}
This means that property setters/getters can apply logic that a mere public field can't
Edit: I'm not exactly sure what field names the CLR gives the backing fields for auto-properties - it's just an example :)
Edit2:
An example of a read only property:
public int SomeProperty { get; }
and finally a public read - private write (for autoproperties)
public int SomeProperty { get; private set; }
Really useful when you can't be bothered to type a backing field in :)
Just remember, if there is a possibility that you wish to apply logic to a member, then a property is the way to go. This is the way a lot of frameworks work (e.g. tracking 'dirty' objects by using a property to tell some sort of object manager that something has changed, this would not be possible using a public field)
Properties can have side-effects, They provide syntactic sugar around 'getter' and 'setter' methods.
public class MyClass {
int sizeValue = 0;
public int Size {
get {
return sizeValue;
}
set {
if ( value < 10 ) throw new Exception("Size too small");
sizeValue = value;
}
}
}
Properties can also have different levels of protection for get and set, you cannot do that with fields.
public class MyOtherClass {
// only this object can set this.
public int Level {
get; private set;
}
// only things in the same assembly can set this.
public string Name {
get; internal set;
}
}
There are a number of important differences between "properties" and "member access".
The most significant is that you can, through a property, make a member read-only (you can access the state, but you cannot change it). Just like "getter()" and "setter()" methods in Java.
You can also return a computed value from a property (generate a value "on-the-fly", as though it were a variable).
Properties can be configured so that:
they are read-only, Public MyProp {get;}
they are write-only Public MyProp {set;}
they are readable by external objects, but can only be set by the class's internals
Public MyProp {get; private set;}
As others have posted, you can also put logic into your getters and setters. For example before allowing the property to bet set to a new value, you can check that the value is acceptable.
You cannot do any of that with a public field.
Basically, a public field is the dumbest sort of property that you can have. Given that .Net now allows autobacking fields for your properties. There is no good reason to use public fields any longer.
If you have Public Int MyAge
I can set it to -200 or 20,000 and there is nothing you can do about it.
If you use a property you can check that age is between 0 and 150, for example.
Edit: as per IanNorton's example (man, that was fast)
public class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public struct Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Your second snippet is a mutable struct. That's a really bad idea, IMO - they behave oddly in various different situations, as values can be copied when you may not expect them to be.
You could create immutable structs of course, and there are times when that's appropriate - but personally I find the reference type behaviour more natural usually. With structs, you also need to worry about the fact that whatever constructors you put in place, it's always possible to set a variable to the default value - so the fields will be zero for numeric types, null for reference types etc. It's annoying to have to deal with the possibility of an invalid object everywhere, whereas with classes you can add appropriate validation to the constructor (or factory methods) to make sure that the only thing you need to worry about is a null reference.
The efficiency argument ends up tricky, as there are pros and cons on both sides, depending on exactly what you do with the objects.
To cut a long answer short (too late?) - I would use classes by default; save value types for things which are natural individual values ("an instant in time", or "an integer" for example).
Here is a link with differences between structs and classes:
http://msdn.microsoft.com/en-us/library/aa288471%28VS.71%29.aspx
It claims structs are more efficient but I would think that pass by ref is more efficient then pass by value for large data.
This may be a problem:
" Although the CLR allows it, C# does
not allow structs to have a default
parameterless constructor. The reason
is that, for a value type, compilers
by default neither generate a default
constructor, nor do they generate a
call to the default constructor. So,
even if you happened to define a
default constructor, it will not be
called and that will only confuse you.
To avoid such problems, the C#
compiler disallows definition of a
default constructor by the user. And
because it doesn't generate a default
constructor, you can't initialize
fields when defining them, like:
Collapse
struct MyWrongFoo {
int x = 1; }
Remember, the compiler puts all this
initialization code into the
constructor (every constructor), and
because there's no default
constructor, you can't do the
initialization.
Now, for the fun part.. You normally
instantiate a struct like this:"
http://www.codeproject.com/KB/cs/structs_in_csharp.aspx
POCOs and DTOs are not the same thing.
A POCO is a business object that would typically have state and behaviour.
A DTO is a lightweight object for transferring state between application layers.
I would obviously use classes for POCOs, and also for DTOs.
For a class instance to work properly, some fields should be properly initialized, what's your strategy to initialize these field, what should be given through constructor, what should be given through property?
My confusion is that, if the constructor requires a long parameter list, it's hard to use, if through properties, i tend to forget to set some properties.
What's the best practice?
You must ask yourself, if your class needs that many things to be created, perhaps it is doing too much. It's a sign that you should reconsider your design, or just how much "work" the constructor is doing.
It is true that you should not be able to create an instance with invalid state; thus the constructor should take all properties you need to be in a valid state.
To a degree, it depends on your model. For example, the ORM I use has the constructor take one parameter; an ID by which it can load all the other properties. It would be annoying if I had to pass them all in (that's the job of the ORM really; to set this object up). So in that sense, you can argue you have an "invalid" object (no properties set). But you'd be wrong; what you actually have is a "blank" or "empty" object. That's not the same as invalid.
So think carefully about what it means for your object to be "invalid". I would consider it invalid if other methods took this object, and threw an exception because something wasn't set. Use this logic to determine what needs to be in the constructor, and what can be set later (by some other process).
This is always a balancing act - you don't want to have constructors that require many parameters but you also don't want to require that a user set many properties before an object is in a valid state. Unfortunately there is no real guidance here as you must use your best judgment for the situation at hand.
Many times you may need to create a composite type which has many properties and many possible configurations (e.g. System.Web.Page). Composite types tend to have simple constructors that take little or no parameters and all values must be set through properties. Composite types are high-level types that are composed of lower-level factored (or primitive) types.
Factored types tend to be simpler, contain less state, and can be completely initialized via their constructors. Examples of factored types are System.String and System.Int32. These types are very simple and tend to be the building blocks of composite types.
If your type is a factored type then try your best to allow consumers to initialize the type completely via the constructor. If your type is a composite type then it is better to offer simple constructors with little or no parameters and require that the consumer configure the instance via property setters.
Now that .NET 3.5 allows you set any property on creation, I generally restrict any constructor with parameters to situations where the instance absolutely must have a value on creation. There really isn't any other reason to add constructor overloads with parameters IMO.
I think the best thing would be to perform validation and generally try to keep constructors with no parameters as it is often a requirement for different .NET libraries.
With validation you will have to check the object's validity, but it is pretty common thing to do. Something among the lines:
public interface IValidateable {
IEnumerable<string> Validate();
}
public class Person : IValidateable {
public string Title { get; set; }
public string First { get; set; }
public string Last { get; set; }
public Address HomeAddress { get; set; }
public Person() {
HomeAddress = new Address();
}
public IEnumerable<string> Validate() {
var errors = new List<string>();
if (string.IsNullOrEmpty(First))
errors.Add("First name is required.");
// And so on...
return errors;
}
}
// Usage
var p1 = new Person();
var p2 = new Person {
First = "Dmitriy"
};
if (p1.Validate().Any()) {
// Do something with invalid object
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have over the course of a few projects developed a pattern for creating immutable (readonly) objects and immutable object graphs. Immutable objects carry the benefit of being 100% thread safe and can therefore be reused across threads. In my work I very often use this pattern in Web applications for configuration settings and other objects that I load and cache in memory. Cached objects should always be immutable as you want to guarantee they are not unexpectedly changed.
Now, you can of course easily design immutable objects as in the following example:
public class SampleElement
{
private Guid id;
private string name;
public SampleElement(Guid id, string name)
{
this.id = id;
this.name = name;
}
public Guid Id
{
get { return id; }
}
public string Name
{
get { return name; }
}
}
This is fine for simple classes - but for more complex classes I do not fancy the concept of passing all values through a constructor. Having setters on the properties is more desirable and your code constructing a new object gets easier to read.
So how do you create immutable objects with setters?
Well, in my pattern objects start out as being fully mutable until you freeze them with a single method call. Once an object is frozen it will stay immutable forever - it cannot be turned into a mutable object again. If you need a mutable version of the object, you simply clone it.
Ok, now on to some code. I have in the following code snippets tried to boil the pattern down to its simplest form. The IElement is the base interface that all immutable objects must ultimately implement.
public interface IElement : ICloneable
{
bool IsReadOnly { get; }
void MakeReadOnly();
}
The Element class is the default implementation of the IElement interface:
public abstract class Element : IElement
{
private bool immutable;
public bool IsReadOnly
{
get { return immutable; }
}
public virtual void MakeReadOnly()
{
immutable = true;
}
protected virtual void FailIfImmutable()
{
if (immutable) throw new ImmutableElementException(this);
}
...
}
Let's refactor the SampleElement class above to implement the immutable object pattern:
public class SampleElement : Element
{
private Guid id;
private string name;
public SampleElement() {}
public Guid Id
{
get
{
return id;
}
set
{
FailIfImmutable();
id = value;
}
}
public string Name
{
get
{
return name;
}
set
{
FailIfImmutable();
name = value;
}
}
}
You can now change the Id property and the Name property as long as the object has not been marked as immutable by calling the MakeReadOnly() method. Once it is immutable, calling a setter will yield an ImmutableElementException.
Final note:
The full pattern is more complex than the code snippets shown here. It also contains support for collections of immutable objects and complete object graphs of immutable object graphs. The full pattern enables you to turn an entire object graph immutable by calling the MakeReadOnly() method on the outermost object. Once you start creating larger object models using this pattern the risk of leaky objects increases. A leaky object is an object that fails to call the FailIfImmutable() method before making a change to the object. To test for leaks I have also developed a generic leak detector class for use in unit tests. It uses reflection to test if all properties and methods throw the ImmutableElementException in the immutable state.
In other words TDD is used here.
I have grown to like this pattern a lot and find great benefits in it. So what I would like to know is if any of you are using similar patterns? If yes, do you know of any good resources that document it? I am essentially looking for potential improvements and for any standards that might already exist on this topic.
For info, the second approach is called "popsicle immutability".
Eric Lippert has a series of blog entries on immutability starting here. I'm still getting to grips with the CTP (C# 4.0), but it looks interesting what optional / named parameters (to the .ctor) might do here (when mapped to readonly fields)...
[update: I've blogged on this here]
For info, I probably wouldn't make those methods virtual - we probably don't want subclasses being able to make it non-freezable. If you want them to be able to add extra code, I'd suggest something like:
[public|protected] void Freeze()
{
if(!frozen)
{
frozen = true;
OnFrozen();
}
}
protected virtual void OnFrozen() {} // subclass can add code here.
Also - AOP (such as PostSharp) might be a viable option for adding all those ThrowIfFrozen() checks.
(apologies if I have changed terminology / method names - SO doesn't keep the original post visible when composing replies)
Another option would be to create some kind of Builder class.
For an example, in Java (and C# and many other languages) String is immutable. If you want to do multiple operations to create a String you use a StringBuilder. This is mutable, and then once you're done you have it return to you the final String object. From then on it's immutable.
You could do something similar for your other classes. You have your immutable Element, and then an ElementBuilder. All the builder would do is store the options you set, then when you finalize it it constructs and returns the immutable Element.
It's a little more code, but I think it's cleaner than having setters on a class that's supposed to be immutable.
After my initial discomfort about the fact that I had to create a new System.Drawing.Point on each modification, I've wholly embraced the concept some years ago. In fact, I now create every field as readonly by default and only change it to be mutable if there's a compelling reason – which there is surprisingly rarely.
I don't care very much about cross-threading issues, though (I rarely use code where this is relevant). I just find it much, much better because of the semantic expressiveness. Immutability is the very epitome of an interface which is hard to use incorrectly.
You are still dealing with state, and thus can still be bitten if your objects are parallelized before being made immutable.
A more functional way might be to return a new instance of the object with each setter. Or create a mutable object and pass that in to the constructor.
The (relatively) new Software Design paradigm called Domain Driven design, makes the distinction between entity objects and value objects.
Entity Objects are defined as anything that has to map to a key-driven object in a persistent data store, like an employee, or a client, or an invoice, etc... where changing the properties of the object implies that you need to save the change to a data store somewhere, and the existence of multiple instances of a class with the same "key" imnplies a need to synchronize them, or coordinate their persistence to the data store so that one instance' changes do not overwrite the others. Changing the properties of an entity object implies you are changing something about the object - not changing WHICH object you are referencing...
Value objects otoh, are objects that can be considered immutable, whose utility is defined strictly by their property values, and for which multiple instances, do not need to be coordinated in any way... like addresses, or telephone numbers, or the wheels on a car, or the letters in a document... these things are totally defined by their properties... an uppercase 'A' object in an text editor can be interchanged transparently with any other uppercase 'A' object throughout the document, you don't need a key to distinguish it from all the other 'A's In this sense it is immutable, because if you change it to a 'B' (just like changing the phone number string in a phone number object, you are not changing the data associated with some mutable entity, you are switching from one value to another... just as when you change the value of a string...
Expanding on the point by #Cory Foy and #Charles Bretana where there is a difference between entities and values. Whereas value-objects should always be immutable, I really don't think that an object should be able to freeze themselves, or allow themselves to be frozen arbitrarily in the codebase. It has a really bad smell to it, and I worry that it could get hard to track down where exactly an object was frozen, and why it was frozen, and the fact that between calls to an object it could change state from thawed to frozen.
That isn't to say that sometimes you want to give a (mutable) entity to something and ensure it isn't going to be changed.
So, instead of freezing the object itself, another possibility is to copy the semantics of ReadOnlyCollection< T >
List<int> list = new List<int> { 1, 2, 3};
ReadOnlyCollection<int> readOnlyList = list.AsReadOnly();
Your object can take a part as mutable when it needs it, and then be immutable when you desire it to be.
Note that ReadOnlyCollection< T > also implements ICollection< T > which has an Add( T item) method in the interface. However there is also bool IsReadOnly { get; } defined in the interface so that consumers can check before calling a method that will throw an exception.
The difference is that you can't just set IsReadOnly to false. A collection either is or isn't read only, and that never changes for the lifetime of the collection.
It would be nice at time to have the const-correctness that C++ gives you at compile time, but that starts to have it's own set of problems and I'm glad C# doesn't go there.
ICloneable - I thought I'd just refer back to the following:
Do not implement ICloneable
Do not use ICloneable in public APIs
Brad Abrams - Design Guidelines, Managed code and the .NET Framework
System.String is a good example of a immutable class with setters and mutating methods, only that each mutating method returns a new instance.
This is an important problem, and I've love to see more direct framework/language support to solve it. The solution you have requires a lot of boilerplate. It might be simple to automate some of the boilerplate by using code generation.
You'd generate a partial class that contains all the freezable properties. It would be fairly simple to make a reusable T4 template for this.
The template would take this for input:
namespace
class name
list of property name/type tuples
And would output a C# file, containing:
namespace declaration
partial class
each of the properties, with the corresponding types, a backing field, a getter, and a setter which invokes the FailIfFrozen method
AOP tags on freezable properties could also work, but it would require more dependencies, whereas T4 is built into newer versions of Visual Studio.
Another scenario which is very much like this is the INotifyPropertyChanged interface. Solutions for that problem are likely to be applicable to this problem.
My problem with this pattern is that you're not imposing any compile-time restraints upon immutability. The coder is responsible for making sure an object is set to immutable before for example adding it to a cache or another non-thread-safe structure.
That's why I would extend this coding pattern with a compile-time restraint in the form of a generic class, like this:
public class Immutable<T> where T : IElement
{
private T value;
public Immutable(T mutable)
{
this.value = (T) mutable.Clone();
this.value.MakeReadOnly();
}
public T Value
{
get
{
return this.value;
}
}
public static implicit operator Immutable<T>(T mutable)
{
return new Immutable<T>(mutable);
}
public static implicit operator T(Immutable<T> immutable)
{
return immutable.value;
}
}
Here's a sample how you would use this:
// All elements of this list are guaranteed to be immutable
List<Immutable<SampleElement>> elements =
new List<Immutable<SampleElement>>();
for (int i = 1; i < 10; i++)
{
SampleElement newElement = new SampleElement();
newElement.Id = Guid.NewGuid();
newElement.Name = "Sample" + i.ToString();
// The compiler will automatically convert to Immutable<SampleElement> for you
// because of the implicit conversion operator
elements.Add(newElement);
}
foreach (SampleElement element in elements)
Console.Out.WriteLine(element.Name);
elements[3].Value.Id = Guid.NewGuid(); // This will throw an ImmutableElementException
Just a tip to simplify the element properties: Use automatic properties with private set and avoid explicitly declaring the data field. e.g.
public class SampleElement {
public SampleElement(Guid id, string name) {
Id = id;
Name = name;
}
public Guid Id {
get; private set;
}
public string Name {
get; private set;
}
}
Here is a new video on Channel 9 where Anders Hejlsberg from 36:30 in the interview starts talking about immutability in C#. He gives a very good use case for popsicle immutability and explains how this is something you are currently required to implement yourself. It was music to my ears hearing him say it is worth thinking about better support for creating immutable object graphs in future versions of C#
Expert to Expert: Anders Hejlsberg - The Future of C#
Two other options for your particular problem that haven't been discussed:
Build your own deserializer, one that can call a private property setter. While the effort in building the deserializer at the beginning will be much more, it makes things cleaner. The compiler will keep you from even attempting to call the setters and the code in your classes will be easier to read.
Put a constructor in each class that takes an XElement (or some other flavor of XML object model) and populates itself from it. Obviously as the number of classes increases, this quickly becomes less desirable as a solution.
How about having an abstract class ThingBase, with subclasses MutableThing and ImmutableThing? ThingBase would contain all the data in a protected structure, providing public read-only properties for the fields and protected read-only property for its structure. It would also provide an overridable AsImmutable method which would return an ImmutableThing.
MutableThing would shadow the properties with read/write properties, and provide both a default constructor and a constructor that accepts a ThingBase.
Immutable thing would be a sealed class that overrides AsImmutable to simply return itself. It would also provide a constructor that accepts a ThingBase.
I dont like the idea of being able to change an object from a mutable to an immutable state, that kind of seems to defeat the point of design to me. When are you needing to do that? Only objects which represent VALUES should be immutable
You can use optional named arguments together with nullables to make an immutable setter with very little boilerplate. If you really do want to set a property to null then you may have some more troubles.
class Foo{
...
public Foo
Set
( double? majorBar=null
, double? minorBar=null
, int? cats=null
, double? dogs=null)
{
return new Foo
( majorBar ?? MajorBar
, minorBar ?? MinorBar
, cats ?? Cats
, dogs ?? Dogs);
}
public Foo
( double R
, double r
, int l
, double e
)
{
....
}
}
You would use it like so
var f = new Foo(10,20,30,40);
var g = f.Set(cat:99);