This question already has answers here:
Why/when should you use nested classes in .net? Or shouldn't you?
(14 answers)
Closed 10 years ago.
Specifically, can anyone give me concrete examples of when or when not to use nested classes?
I've known about this feature since forever, but never had a reason to use it.
Thanks.
When the nested class is only used by the outer class, a great example, no longer necessary, is for an enumerator class for a collection.
another example might be for a enum to replace a true false parameter used by a method within a class, to clarify the call signature...
instead of
public class Product
{
public void AmountInInventory(int warehouseId, bool includeReturns)
{
int totalCount = CountOfNewItems();
if (includeReturns)
totalCount+= CountOfReturnedItems();
return totalCount;
}
}
and
product P = new Product();
int TotalInventory = P.AmountInInventory(123, true);
which leaves it unclear as to what 'true' means, you could write:
public class Product
{
[Flags]public enum Include{None=0, New=1, Returns=2, All=3 }
public void AmountInInventory(int warehouseId, Include include)
{
int totalCount = 0;
if ((include & Include.New) == Include.New)
totalCount += CountOfNewItems();
if ((include & Include.Returns) == Include.Returns)
totalCount += CountOfReturns();
return totalCount;
}
}
product P = new Product();
int TotalInventory = P.AmountInInventory(123, Product.Include.All);
Which makes the parameter value clear in client code.
The two places where I use nested classes:
The nested class is used exclusively by the outer class, and I want completely private scope.
The nested class is used specifically to implement an interface defined elsewhere. For example, implementing an enumerator falls into this category.
You really only want to use nested classes when you are sure the nested class doesn't make sense that it would be used anywhere else.
For example, if you needed to create a list of several types of object associated together with functions and member information about that set of objects for a short time (like methods or properties), you could use a nested class to do that. Maybe you need to create a list of all combinations of some type of object, and then mark all combinations that have a certain property. That would be a good case for a nested class.
If you don't need methods on the nested class, you can probably just use a struct but I don't know if IL treats them any differently.
I sometimes use this for simple helper classes that I need for a function or two inside of the parent class.
For a practical example, see this question asked earlier this morning:
Make an object accessible to only one other object in the same assembly?
Summary: you can nest an associated data class inside it's business object.
I've seen cases of nested classes when a special purpose data structure is used only within one class, or a certain exception is thrown and caught only within one class.
I nest classes when I have a helper class which has no need to be visible to any other object in the system. This keeps the visibility as constrained as possible which helps prevent unintended uses of the class
Following Uncle Bob's 'rules' on cohesion should find that you actually create quite a number of nested (and nested, nested!) classes. These could be made non-nested but only if you have other clients that reference them now.
I'd like to improve on my previous answer!
A specific area where I use nested classes regularly is enabling Interface Injection and Inversion of Control. Example...
public class Worker
{
private IHelper _helper;
public Worker()
: this (new DefaultHelper())
{
}
public Worker(IHelper helper)
{
this._helper = helper;
}
private class DefaultHelper : IHelper
{
}
}
Related
I've got several C# classes each with similar properties.
(They're part of an SDK and their code can’t be changed.)
Person.Name
Product.Name
Order.Name
I want to use these classes polymorphically, but they don’t implement a common interface or derive from a common base class, so that’s not possible.
To get around this, I’d like to wrap each one in another class that does implement a common interface, and wire-up each class property to its corresponding interface property.
What would be a suitable name for the wrapper classes? Wrapper, Decorator, Adaptor, Proxy? Does this pattern have a name? Is there a better approach?
(I don't want to use dynamic duck-typing or an impromptu interface.)
It looks like Adapter, because you are adapting the existing interfaces to the specific requirements.
(I don't want to use dynamic duck-typing or an impromptu interface.)
So what is wrong with a NamedObject?
public class NamedObject
{
public string Name { get; set; }
}
It literally says what it is, nothing less, nothing more.
I'd stick with CodeCaster's idea, and perhaps with a dash of Func<T> for no other reason than I get withdrawal symptoms when I don't use angle brackets...
public class NamedEntity
{
public string Name { get { return _getName(); } }
private Func<string> _getName;
public NamedObject(Func<string> getName)
{
_getName = getName;
}
}
And then call thus:
var named = new[]
{
new NamedEntity(() => person.Name),
new NamedEntity(() => product.Name),
new NamedEntity(() => order.Name)
};
The added benefit with this is when the value of the property changes on the target object, it changes within the NamedEntity reference too via the Func, this means within the life span of the objects you can get away with wrapping them once. You can also do the inverse with Funcs that set values as well as get, and can adapt more properties.
I am not immediately sure what pattern this represents (if any), though I would guess Adapter pattern (which is a type of wrapper pattern). However, it could also be argued to be a Proxy pattern. Not sure really.
Maybe you can just change the namespace and keep the names of the original classes.
Technically, I think the most correct name would be Adapter, see this question.
Adapter is used when you have an abstract interface, and you want to map that interface to another object which has similar functional role, but a different interface.
You don't have abstract interface, but "similar functional role, but a different interface".
All, I have an application that needs to attach and detach multiple SQL databases regularly. I want to create a class that holds all of these databases as a collection that can be iterated over. To do this I am inheriting from ICollection, but there is some thinkg I am not understanding:
class SqlDataBases : ICollection<SqlDb>
{
private List<SqlDb> dbColl;
public SqlDataBases()
{
dbColl = new List<SqlDb>();
}
// Add an index to the collection.
public SqlDb this[int _nIndex]
{
get { return (SqlDb)dbColl[_nIndex]; }
set { dbColl[_nIndex] = value; }
}
// et al.
}
public class DbEnumerator : IEnumerator<SqlDb>
{
// ...
}
class SqlDb
{
private string strMdfFullPath;
private string strLdfFullPath;
private bool bIsAttached;
public SqlDb(string _strMdfFullPath, string _strLdfFullPath, bool _bIsAttached)
{
this.strMdfFullPath = _strMdfFullPath;
this.strLdfFullPath = _strLdfFullPath;
this.bIsAttached = _bIsAttached;
}
}
My question is "why inherit from ICollection at all, when you have to add methods such as 'Add', 'Contains' etc. yourself? Or do you have to do this yourself as suggested in MSDN? I have been reading "C# in a Nutshell" and this question is something that stands out unaddressed in this great book.
I apologise, I know I am missing something here...
My question is "why inherit from ICollection at all, when you have to add methods such as 'Add', 'Contains' etc. yourself?
ICollection<T> is an interface - it just specifies the members that you have to implement. If you want to derive from something which already has an implementation, look at Collection<T>. You would implement the interface yourself if you wanted to create your own collection data structure with its own special characteristics - I doubt that you want to do that.
To be honest, it's not clear why you want your own class here at all - why not just use List<SqlDb> in the client code directly?
Have you thought about using List<SqlDb> directly?
It's not obvious to me what you hope to gain by the SqlDataBases class.
If you can't use List<SqlDb> directly, think about inheriting from List<SqlDb> rather than ICollection<SqlDb>.
Interfaces are only skeletons. They aren't containing any logic, they are containing only the signatures of all method, property etc.
Interfaces
The reason to inherit from ICollection<> is to create your own custom collection type. Then, anywhere a method has an input variable of ICollection<>, because you inherited from ICollection<>, your new custom collection type can be passed in.
In your case, you could simply use List<> until you find a need to create a custom collection.
Answering "why inherit from ICollection at all, when you have to add methods such as 'Add'":
you don't need to inherit ICollection if you don't need/want to have Add/Next etc.
I am working on a class library using C#. I have designed 3 main classes to help model our data. They are designed such that class A contains a list of class B instances, and class B contains a reference to a class C instance, ie:
public class Policy
{
public List < PolicyTerm > myTerms;
person Customer;
string PolicyNumber;
}
public class PolicyTerm
{
public Billing myBill;
Datetime effectivedate;
List < Activities > termActivities;
public doAction()
{
use value from Policy, like PolicyNumber;
}
}
public class Billing
{
float remainingBalance;
Datetime nextDueDate;
public void doSomething()
{
reference value from PolicyTerm, such as effective date;
use value from Policy, such as PolicyNumber;
}
}
The problem I have is when I try to use a method within PolicyTerm or Billing that needs data from the containing class. In the example above, this would be the method "doSomething" trying to use a value from PolicyTerm, like the effective date for the term in requesting or saving data to our database.
I am wondering if I have the correct design for my classes because of this scenario. Should I just add a reference to the "parent" class within the child classes, in order to make the parent's data available? Or do I need to rethink the overall structure and design of the code?
I feel like the class design works well for modeling the data and our business rules, but it does create a few limitations like the above situation. I liked the separation of the PolicyTerm and Billing for the ability to allow that code to be modified and tested independently. Also, I feel like it keeps each section smaller and simpler.
Any advice that can be provided would be much appreciated.
Update: Code block was updated to provide more details on the code in question.
If doSomething() always needs the reference to the C object's parent, you should indeed put this reference into C where you can ensure that it refers to the correct B instance. OTOH if that reference is not always the parent, but still it is always going to refer to the same B instance, it still suggests turning it into a member of C. OTOH if doSomething() can be called with varying references, that reference should be kept as a method parameter.
It is not bad per se to put a reference from child to parent, or to have a mutual dependency between two classes - it depends on the context. The consequence of this is that the two classes can not be used separately, so in fact they form a component. This may or may not be acceptable for you.
Components in general can consist of multiple classes - a collection with its items and iterator(s) is in fact a typical example. However, it is advisable to express the logical dependency between these classes on the physical level as well, e.g. by making one class an inner class of the other, or making both classes inner classes in a third class.
This really depends on the situation. In general, unless there is a clear, obvious relationship between classes "B" and "C", it's a red flag that C.doSomething() would require access to B, since C is contained within B...
However, a method in B requiring access to C makes sense, since C is a member within B.
That being said, there are times that this is appropriate. Without knowing your actual classes, and what they represent, its difficult to say more...
Two classes shouldn't, but two interfaces is OK.
Of course, the smaller the interfaces the better. You'll find that if the interfaces are small enough (which they should be - see Interface Segregation Principal), you won't actually need 2 of the same.
Creating a reference to your required class doesn't seem a bad idea at all. If it's required, you could make Class C's constructor take the reference to Class B and store it in a member variable.
I'm working on a project at the moment with a couple of classes behave like this.
Another option which might be a bit more "sane" is to have an event on class C, that's something like "SuchAndSuchDataRequired." Class B could then listen to that event when it gets the instance of C. Class C fires the event from within doSomething() when it needs the data from B, B then returns the data in it's event handler and bingo - class C has the data and doesn't even know it came from class B.
The general rule of thumb is keep the data as close as possible to the functions/methods/classes that will be using it. This will keep things decoupled and you won't have to have both classes referencing each other, which actually makes you have to create an extra object that might not be necessary.
And like ChaosPandion said: please post some more specific code so we can better help you.
Edit:
If you B references C and C references B, then you might want to consider putting the two together as one object. This works best if the two classes are not completely different. If there is no real distinguishable difference, then just put it together in one class ... that could simplify the whole thing.
In my opinion your modelling seems a bit skewed i.e. why is there a property of type person within policy and why have a List of a concrete implementation in Policy i.e. PolicyTerm. This couples the classes together and doesn't feel right - i.e. Policy HAS A customer? Should be Customer HAS A Policy
Can I suggest the following (quickly modelled and not tested but you should be able to see what I'm getting at)
public class Customer()
{
prop name,etc,etc;
public List<IPolicyTerm> Policies{get;set;}//I use public getters and setters throughout but you need to choose what level of encapsulation you want
private Account customerAccount{get;set}
public Customer()
{
//ctor
customerAccount = doDbCall;
Policies = doDbCall;
}
public decimal GetCurrentPolicyCost()
{
decimal cost = 0;
foreach(var policy in Policies)
{
if(policy.DueDate < DateTime.Now){
cost += policy.GetCost(); //for example but you can call whatever is defined at the interface level
}
}
return cost;
}
public bool HasEnoughFunds()
{
return customerAccount.Balance >= GetCurrentPolicyCost();
}
//keeping Account hidden in Person as Person has a reference to Account.
//By doing so there is type coupling between the two classes
//BUT you can still modify Policies away from Person
private class Account
{
//should only contain properties and I assume only one 'Account' per person
}
}
public interface IPolicyTerm
{
object Id{get;set}
DateTime DueDate {get;set;}
decimal GetCost();
}
///now we can have polymorphic Policies i.e. the cost of one can be calculated differently based on policy
public class LifeCoverPolicy : IPolicyTerm
{
public object Id;
public DateTime DueDate{get;set;}
public decimal GetCost()
{
return 10;
}
}
I am not sure if there is already a nomenclature for this, but for the sake of this question lets define two terms: peer implementation or nested implementation to illustrate how you implement collection classes in a data model that contains many parent/child entity relationships.
I use the term peer to describe the scenario where you implement the collection classes in your model layer along side with the entity classes essentially making them peers in your API like so:
public class ParentEntity
{
private ChildEntityCollection children;
}
public class ChildEntity
{
}
public class ChildEntityCollection : ICollection<ChildEntity>
{
}
The main advantage here is that you can reuse the collection class in other entity classes that happen to store children of the same type.
I use the term nested to describe the scenario where you implement them as a nested class like so:
public class ParentEntity
{
private ChildEntityCollection children;
public class ChildEntityCollection : ICollection<ChildEntity>
{
}
}
public class ChildEntity
{
}
The main advantage here is that each parent can implement their own collection class to store its children in manner that is most optimized for that specific parent. For example, one parent entity may find that an array data structure works well whereas another may use a splay tree (obscure I know, but it illustrates my point well).
I have noticed that Microsoft uses both idioms in the various .NET related frameworks. The System.Windows.Forms namespace seems to rely heavily on nested implementations. I tend to find myself prefering this method as well even though it requires more work.
Recommendations, comments, alternative ideas?
Regardless of what Microsoft might have done in the past, the current .NET API design guidelines discourage creation of nested classes that are visible outside their parent classes. See http://msdn.microsoft.com/en-us/library/ms229027.aspx for details.
Another option is to nest the collection class in the child class, and just name it Collection. That way, you always get Child.Collection as the name.
public class Child
{
public class Collection : ICollection<Child>
{
}
}
public class Parent
{
private Child.Collection children;
}
Personally I prefer the peer implementation, it promotes reuse of code which I don't think the nested implementation does. If another class needs to implement a different way of storing a collection of the same elements then another class can easily be implemented for that scenario without limiting code reuse.
A nested setup can also lead some developers to tightly couple their code to the parent class.
I also prefer the peer approach. There's really no reason to nest the collection unless you will never use it outside of its parent class (in that case, it should be a private nested class.)
I would only use the nested arrangement when there is only one Entity in the Domain model that can logically contain the child Entities.
For example if you had a PieceOfMail class and a MailPieces collection class
class PieceOfMail { }
class MailPieces: Collection<PieceOfMail> { }
then the ShipingCompany class, and the MailBox class, and the PostOffice Class, and the MailRoute class, and the MailManBag class, could ALL have a constituent property typed as MailPieces, so I'd use the "peer" technique.
But otoh, in the same Domain, if you had a class representing a type of PostageDiscount, and a collection class representing a set of discounts to be applied to a shipment, it might be the case that ONLY the ShipmentTransaction class could logically contain a collection of those discounts, then I'd use the nested technique...
Do you really need a ChildEntityCollection? Why not use a collection type that is provided?
//why bother?
//public class ChildEntityCollection : ICollection<ChildEntity>{}
public class ParentEntity
{
//choose one
private ChildEntity[] children;
private List<ChildEntity> childrenInList;
private HashSet<ChildEntity> childrenInHashSet;
private Dictionary<int, ChildEntity> childrenInDictionary;
// or if you want to make your own, make it generic
private Balloon<ChildEntity> childrenInBalloon;
}
public class ChildEntity
{
}
I generally try to avoid generating specific collection classes. Sometimes you may need a special class, but in many cases you can simply use generic classes like Collection<T> and ReadOnlyCollection<T> from the System.Collection.ObjectModel namespace. This saves a lot of typing. All your collections derive from IEnumerable<T> etc. and are easily integrated with LINQ. Depending on your requirements you could also expose your collections as ICollection<T> or another collection interface and then let classes with specific requirements use highly optimized generic collections.
public class ParentEntity {
Collection<ChildEntity> children = new Collection<ChildEntity>();
public Collection<ChildEntity> Children {
get {
return this.children;
}
}
}
You can also wrap an IList<T> like this:
public class ParentEntity {
// This collection can be modified inside the class.
List<ChildEntity> children = new List<ChildEntity>();
ReadOnlyCollection<ChildEntity> readonlyChildren;
public ReadOnlyCollection<ChildEntity> Children {
get {
return this.readOnlyChildren
?? (this.readOnlyChildren =
new ReadOnlyCollection<ChildEntity>(this.children));
}
}
}
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);