My colleague and I have been having a discussion about what Collections should be called.
For example:
Class Product - Collection - Class Products
or
Class Product - Collection - Class ProductCollection
I've had a look around to see if I can see any guidelines or reasons for using one or the other but nothing seems to spring out. The framework seems to use both variants for example. The argument I can see is that a class that has a collection of products variable should be called Products but it should be of type ProductCollection.
Which is correct if any?
In the same vane is there a standard for the naming of return variable for a function. e.g. retVal?
We mainly code in C#, although I'm not sure that affects my question.
I would say that with generics there should rarely ever be a reason to create a custom collection type. But if you must I would say that ProductCollection would best fit the naming conventions of the framework.
Still, consider using a List<Product> or Collection<Product> or better yet IList<Product> or ICollection<Product>.
Edit: This is in response to MrEdmundo's comments below.
In your case you have two choices. The most obvious choice would be to use inheritance like this:
class Ball { }
class BallCollection : List<Ball>
{
public String Color { get; set; }
public String Material { get; set; }
}
I say obvious because it seems like the best idea at first glance but after a bit of thought it becomes clear that this is not the best choice. What if you or Microsoft creates a new SuperAwesomeList<T> and you want to use that to improve the performance of your BallCollection class? It would be difficult because you are tied to the List<T> class through inheritance and changing the base class would potentially break any code that uses BallCollection as a List<T>.
So what is the better solution? I would recommend that in this case you would be better off to favor composition over inheritance. So what would a composition-based solution look like?
class Ball { }
class BallCollection
{
public String Color { get; set; }
public String Material { get; set; }
public IList<Ball> Balls { get; set; }
}
Notice that I have declared the Balls property to be of type IList<T>. This means that you are free to implement the property using whatever type you wish as long as that type implements IList<T>. This means that you can freely use a SuperAwesomeList<T> at any point which makes this type significantly more scalable and much less painful to maintain.
Products is certainly not correct IMHO. A non-static class name should represent a noun (not plural), because you should be able to say "x is a [classname]".
Obviously, Products doesn't fit in that scheme. ProductCollection does:
Illustration:
var products = new Products(); // products is a Products
var products = new ProductCollection(); // products is a ProductCollection
Which one "sounds right" ?
Another thing about naming collection classes: I usually try to name collection classes in such way that it is clear what kind of collection it is.
For example:
class ProductCollection: can only be enumerated and the Count retrieved (i.e. only implements ICollection interface(s))
class ProductList: a list that can be manipulated using Add(), Insert(), etc. (i.e. implements IList interface(s))
class ProductDictionary: a dictionary of products accessible by some key (i.e. implements IDictionary interface(s))
The last one can be ambiguous if there could be a doubt what the key of the dictionary is, so it's better to specify what the key type is (like ProductDictionaryByString). But to be honest, I rarely name it this way because most of the time the key will be a string anyway.
The .NET Framework frequently uses a "Collection" postfix for its collection types. StringCollection, ObservableCollection, KeyedCollection, etc. So go with ProductCollection.
Noticed nobody answered you on the retVal stuff (Or I could just be getting blind). Although I'm not an expert; on the matter of the retVal issue I'm not 100% sure what you mean by "naming of return variable", but if you mean stuff like this:
public void GetSomething(out object retVal)
{
retVal = ThingFactory.CreateSomething();
}
I would say, no matter what the convention is, don't do it. It's very annoying. Just return the value instead. If you need to return more than one thing, then I would think the method either does more than one thing (which a method shouldn't) or those things should be wrapped up in some sort of logical class that could be returned instead.
If instead by "naming of return variable" you mean stuff like this:
var retVal = ThingFactory.CreateSomething();
Then I would say name the variable according to what it is. What it is going to be used for. If its a list of cars, call it listOfCars, if it's a piece of bread to be eaten later, call it pieceOfBread or pieceOfBreadToBeEatenLater.
Hope that helped and that it wasn't too far off into a field somewhere :p
Thesaurus.com
Look no further. No longer will you mull over pluralized singularity. Just fasten one of these plural-protectors to your object's name:
Jumble
Gob
Trove
Miscellany
Vocab
Load
Agglomeration
Mound
Series
Lexicon
Muster
Glossary
Hoard
Swarm
Group
Cluster
Convoy
Assemblage
Herd
Mob
Batch
Amassment
Pile
Bank
Congregation
Clump
Volume
Set
Reserve
Compilation
Flock
Army
Make it fun.
Related
public enum RelationType { Subclass, HasArm, HasLeg };
public RelationType RelationShipType { get; set; }
public static IOwlRelation AddSubClassRelation(IOwlClass parent, IOwlClass child)
{
return new OwlRelation
{
Parent = parent,
Child = child,
RelationShipType = RelationType.Subclass
};
}
So let's say this was in a OwlRelation class and now in the consumer class first I create a OwlRelation object by saying like
OwlRelation r1 = OwlRelation.AddSubClassRelation( someParent, someChild);
and also have a method like AddRelation(OwlRelation) that I can pass that r1 object to it, now in the body of this method I can check and see what was the value of the enumeration on this object and some stuff based on that value.
So that's the reason I have defined that Enumeration type in the OwlRelation class. BUT I think this is not the correct way of axchieving this and prob I just don't have enough expertise to figure it out. So what do you think is the correct way of doing this?
You could implement different relation types as different classes.
public abstract class OwlRelation : IOwlRelation
{
// Implement infrastructure common to all relation types
}
public SubclassOwlRelation : OwlRelation
{
// Implement things specific to Subclass-relations
}
public HasArmOwlRelation : OwlRelation
{
// Implement things specific to HasArm-relations
}
...
With your implementation you are likely to run into code like this one
switch (relation.RelationshipType) {
case RelationshipType.Subclass:
DoSomeSubclassStuff(relation);
break;
case RelationshipType.HasArm:
DoSomeArmStuff(relation);
break;
case RelationshipType.HasLeg:
DoSomeLegStuff(relation);
break;
}
With an object-oriented approach the corresponding code looks like this
relation.DoSomeStuff();
I'm not sure what you are trying to do. From the other direction, the two correct ways to use an enum are:
You have a mutually-exclusive set of values, the total number of which are less than the integer-type you are basing the enum on (int is the default, long is the largest possible), and you can reasonably list every one of them (or expect users to know the number that corresponds with missing items, due to some external standard).
You have a non-mutually-exclusive set of values, which you can combine with binary operators so that if e.g. Read is 1, Write is 2 and Execute is 4, then the ability to read and excecute, but not write is 5 (1 | 4).
Now, I haven't looked at the Web Ontology Language (I'm guessing that's the sort of OWL you mean) in a long time, but I don't see how Arm and Subclass fits into this at all (nor remember anything about arms in OWL). But I also don't see how it fits into anything else - I don't see either the question "Is it an arm, or a subclass?" makes sense (which would fit enum-use 1) nor the question "Is it an arm, a subclass, or both, or neither?" makes sense (which would fit enum-use 2).
So, not much of an answer, but hopefully enough on using enum to help a bit.
I think it's a typical problem and it's solved by applying strategy pattern.
So it would be different RelationStrategy subclasses as #Olivier has suggested.
You can read about it here
I'm trying to explain to my team why this is bad practice, and am looking for an anti-pattern reference to help in my explanation. This is a very large enterprise app, so here's a simple example to illustrate what was implemented:
public void ControlStuff()
{
var listOfThings = LoadThings();
var listOfThingsThatSupportX = new string[] {"ThingA","ThingB", "ThingC"};
foreach (var thing in listOfThings)
{
if(listOfThingsThatSupportX.Contains(thing.Name))
{
DoSomething();
}
}
}
I'm suggesting that we add a property to the 'Things' base class to tell us if it supports X, since the Thing subclass will need to implement the functionality in question. Something like this:
public void ControlStuff()
{
var listOfThings = LoadThings();
foreach (var thing in listOfThings)
{
if (thing.SupportsX)
{
DoSomething();
}
}
}
class ThingBase
{
public virtual bool SupportsX { get { return false; } }
}
class ThingA : ThingBase
{
public override bool SupportsX { get { return true; } }
}
class ThingB : ThingBase
{
}
So, it's pretty obvious why the first approach is bad practice, but what's this called? Also, is there a pattern better suited to this problem than the one I'm suggesting?
Normally a better approach (IMHO) would be to use interfaces instead of inheritance
then it is just a matter of checking whether the object has implemented the interface or not.
I think the anti-pattern name is hard-coding :)
Whether there should be a ThingBase.supportsX depends at least somewhat on what X is. In rare cases that knowledge might be in ControlStuff() only.
More usually though, X might be one of set of things in which case ThingBase might need to expose its capabilities using ThingBase.supports(ThingBaseProperty) or some such.
IMO the fundamental design principle at play here is encapsulation. In your proposed solution you have encapsulated the logic inside of the Thing class, where as in the original code the logic leaks out into the callers.
It also violates the Open-Closed principle, since if you want to add new subclasses that support X you now need to go and modify anywhere that contains that hard-coded list. With your solution you just add the new class, override the method and you're done.
Don't know about a name (doubt such exists) but think of each "Thing" as a car - some cars have Cruise Control system and others do not have.
Now you have fleet of cars you manage and want to know which have cruise control.
Using the first approach is like finding list of all car models which have cruise control, then go car by car and search for each in that list - if there it means the car has cruise control, otherwise it doesn't have. Cumbersome, right?
Using the second approach means that each car that has cruise control come with a sticker saying "I has cruise control" and you just have to look for that sticker, without relying on external source to bring you information.
Not very technical explanation, but simple and to the point.
There is a perfectly reasonable situation where this coding practice makes sense. It might not be an issue of which things actually support X (where of course an interface on each thing would be better), but rather which things that support X are ones that you want to enable. The label for what you see is then simply configuration, presently hard-coded, and the improvement on this is to move it eventually to a configuration file or otherwise. Before you persuade your team to change it I would check this is not the intention of the code you have paraphrased.
The Writing Too Much Code Anti-Pattern. It makes it harder to read and understand.
As has been pointed out already it would be better to use an interface.
Basically the programmers are not taking advantage of Object-Oriented Principles and instead doing things using procedural code. Every time we reach for the 'if' statement we should ask ourselves if we shouldn't be using an OO concept instead of writing more procedural code.
It is just a bad code, it does not have a name for it (it doesn't even have an OO design). But the argument could be that the first code does not fallow Open Close Principle. What happens when list of supported things change? You have to rewrite the method you're using.
But the same thing happens when you use the second code snippet. Lets say the supporting rule changes, you'd have to go to the each of the methods and rewrite them. I'd suggest you to have an abstract Support Class and pass different support rules when they change.
I don't think it has a name but maybe check the master list at http://en.wikipedia.org/wiki/Anti-pattern knows? http://en.wikipedia.org/wiki/Hard_code probably looks the closer.
I think that your example probably doesn't have a name - whereas your proposed solution does it is called Composite.
http://www.dofactory.com/Patterns/PatternComposite.aspx
Since you don't show what the code really is for it's hard to give you a robust sulotion. Here is one that doesn't use any if clauses at all.
// invoked to map different kinds of items to different features
public void BootStrap
{
featureService.Register(typeof(MyItem), new CustomFeature());
}
// your code without any ifs.
public void ControlStuff()
{
var listOfThings = LoadThings();
foreach (var thing in listOfThings)
{
thing.InvokeFeatures();
}
}
// your object
interface IItem
{
public ICollection<IFeature> Features {get;set;}
public void InvokeFeatues()
{
foreach (var feature in Features)
feature.Invoke(this);
}
}
// a feature that can be invoked on an item
interface IFeature
{
void Invoke(IItem container);
}
// the "glue"
public class FeatureService
{
void Register(Type itemType, IFeature feature)
{
_features.Add(itemType, feature);
}
void ApplyFeatures<T>(T item) where T : IItem
{
item.Features = _features.FindFor(typof(T));
}
}
I would call it a Failure to Encapsulate. It's a made up term, but it is real and seen quite often
A lot of people forget that encasulation is not just the hiding of data withing an object, it is also the hiding of behavior within that object, or more specifically, the hiding of how the behavior of an object is implemented.
By having an external DoSomething(), which is required for the correct program operation, you create a lot of issues. You cannot reasonably use inheritence in your list of things. If you change the signature of the "thing", in this case the string, the behavior doesn't follow. You need to modify this external class to add it's behaviour (invoking DoSomething() back to the derived thing.
I would offer the "improved" solution, which is to have a list of Thing objects, with a method that implements DoSomething(), which acts as a NOOP for the things that do nothing. This localizes the behavior of the thing within itself, and the maintenance of a special matching list becomes unnecessary.
If it were one string, I might call it a "magic string". In this case, I would consider "magic string array".
I don't know if there is a 'pattern' for writing code that is not maintainable or reusable. Why can't you just give them the reason?
In order to me the best is to explain that in term of computational complexity. Draw two chart showing the number of operation required in term of count(listOfThingsThatSupportX ) and count(listOfThings ) and compare with the solution you propose.
Instead of using interfaces, you could use attributes. They would probably describe that the object should be 'tagged' as this sort of object, even if tagging it as such doesn't introduce any additional functionality. I.e. an object being described as 'Thing A' doesn't mean that all 'Thing A's have a specific interface, it's just important that they are a 'Thing A'. That seems like the job of attributes more than interfaces.
Or why is the following impossible:
class Material
{
class Keys
{
...
}
Material.Keys Keys { get; set; } // Illegal
}
I don't see any possible ambiguity. When accessed by instance, return the property. When access statically, return the class. Or am I missing something?
I'm not asking for a "fix" (I know I could just name it differently, like MaterialKeys or the like), but more of a technical reason behind this limit.
But imagine you had this:
class Material
{
class Keys
{
...
}
static Material.Keys Keys = new Keys();
}
Now both are at "static" scope. Now, can the compiler disambiguate in all cases? If not, then this can't be allowed.
I suppose it's possible that the disambiguation would work for static fields/properties/methods, and not for instance members. Or the other way around. If that were the case, would you want the language specification to allow an instance member to have the same name as an internal class, but disallow it for statics? That would just be confusing.
But then, having a member match the name of an internal class is pretty confusing anyway.
"Anything that's not ambiguous should be legal" is absolutely NOT a design principle of the C# language. The C# language is designed to be a "pit of quality" language; that is, the rules of the language should throw you into a pit full of clearly correct code, and you have to work to climb out of the pit to turn it into incorrect code. The idea that "whatever is not ambiguous should be legal" works in most cases directly against the concept of a "pit of quality" language.
Furthermore, your idea that I need to provide you a justification for not doing a feature is backwards. We don't ever need to provide justification for not doing a feature. Rather, proposed features must be justified by demonstrating that their benefits outweigh their enormous costs. Features are very expensive and we have a limited budget; we must only do the very best features to yield their benefits to our customers.
Your proposed feature enables the easy production of code that is brittle and confusing; it helps make C# into a "pit of despair" language instead of a "pit of quality" language. Features which add brittleness and confusion to the language must add an enormous benefit to compensate for those costs. What is in your opinion the enormous benefit that this feature adds to the language that justifies its costs?
If the answer is "there is no such benefit" then now you know why the language doesn't have that feature: because it makes the language worse, net.
If there is a benefit, I'm happy to consider its merits for hypothetical future versions of the language.
You said,
When accessed by instance, return the property. When access statically, return the class.
But what if you say just Keys somewhere inside Material? Is this a static or instance access? Does this refer to the property Keys or the nested type Keys? It is actually ambiguous.
For example,
class Material
{
class Keys
{
public static int Length;
}
string Keys { get; set; }
public void Process()
{
// Does this refer to string.Length (via property Keys)
// or Material.Keys.Length? It actually refers to both.
Console.WriteLine(Keys.Length);
}
}
As pointed out in the comments, this is not the whole story; but almost. It is valid to have a property named Color of the type Color and there is no clash:
public Color Color { get; set; }
Color.FromName(...) // refers to static method on the type ‘Color’
Color.ToString() // refers to instance method on the property’s value
But this is easy to resolve simply because things in the current scope win over things in more outer scopes:
public class MyType { public string FromName(string name) { return null; } }
public MyType Color;
Color.FromName(...) // unambiguously refers to MyType::FromName(string)
// via the property Color
Not so easy in your example — the nested class Keys and the property Keys are in the same scope (have the same declaring type). How do you decide which to give priority? And even if you did decide to give one of them priority, this would be only marginally useful because you could still only have two things of the same name, and one would have to be static and the other instance.
My answer approaches the question from a slightly different perspective, compared to the other questions. Of the following two statements in a C# language specification:
The same identifier may not be used in different definitions within one scope
and
The same identifier may not be used in different definitions within one scope, unless it is probably impossible for any ambiguity to arise when the identifier is used
, the first is much simpler.
Simplicity is a key goal in language design, because simpler languages are easier for compiler and interpreter authors to implement, easier for tools to generate and manipulate, easier for beginners to learn, and easier for programmers to understand. When considering any language feature, the complexity that that feature adds to the language should be considered as a negative, and must therefore be balanced by an at least equal measure of usefulness. As you stated yourself, allowing this would add no real functionality (as it is so easy to work around), so there was no compelling reason to further complicate the C# spec by including it.
Because the nested class Keys is a member of Material as is the property Keys. You've got two members called Keys.
In the same way you can't have two properties called the same thing:
public class Bar
{
private bool Foo { get; set; }
private string Foo { get; set; }
}
When you access Foo which one are you trying to access?
public class Material : Keys
{
private Keys K { get; set; }
}
public class Keys
{
}
Works fine, but is probably not what you're after.
Consider the following code:
class Program
{
static void Main(string[] args)
{
Department deathStar = new Department { Name = "Death Star" };
Console.WriteLine("The manager of {0} is {1}.", deathStar.Name, deathStar.Manager.FullName);
deathStar.Manager.FirstName = "Lord";
Console.WriteLine("The manager of {0} is {1}.", deathStar.Name, deathStar.Manager.FullName);
Console.ReadLine();
}
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get
{
return this.FirstName + " " + this.LastName;
}
}
}
public class Department
{
public string Name { get; set; }
public Person Manager { get; private set; }
public Department()
{
this.Manager = new Person { FirstName = "Darth", LastName = "Vader" };
}
}
which produces the following output:
The manager of Death Star is Darth Vader.
The manager of Death Star is Lord Vader.
Even though I can't change Manager to be a different or new instance of Person (private set accessor), I can change it's properties (which have public set accessors).
So, is assigning a value to a property through a set accessor via its container's get accessor a bad thing? In other words, is this a code smell?
EDIT:
This is just a sample to illustrate a point. Person and Department were created for this sample only.
Not necessarrily.
For example, look at the parameters collection on a SqlCommand object. You can change the items in the collection, but you can't assign a new parameters collection to the command object.
Take your example, if you had a UI maintaining Person objects, and you needed to change a persons first name, it's perfectly valid to change the persons first name, leave the last name and PersonId fields alone, then update a database table using the PersonId field.
It all sounds OK to me
Yes, this is a code smell.
While this seems like a fairly harmless practice, public properties expose the fields of your class to arbitrary change and create needless dependence on implementation details. You may as well be using a struct. (I'm not implying that structs are bad either. Procedural programming is just as useful as OOP. It all depends on the problem being solved) The point of encapsulation is to hide implementation details from the class' dependents. Rather you should expose abstract interfaces that allow dependent classes to modify the internal data without needing to know its implementation. Consider the following examples:
public interface Vehicle {
double FuelTankCapacityInGallons{get;}
double GallonsOfGasoline{get;}
}
public interface Vehicle {
double getPercentFuelRemaining();
}
Both interfaces will get you the amount of remaining gasoline. The first through concrete terms, the second through abstraction. If the size of the tank changes or you need to implement a European car the first example would require changes to both the Vehicle and whatever class is using it. While the second would only require changes to the Vehicle implementation.
The example I used is from the book Clean Code - A Handbook of Agile Software Craftsmanship by Robert C. Martin.
I would also look up Law of Demeter.
I'd say that the line:
deathStar.Manager.FirstName = "Lord";
is perfectly clear in its intent, so it doesn't bother me.
What does bother me is the private set on Manager.
This means that once a department is created, it's manager can never be changed.
As a model for reality, this is a big time smell.
Is it "a bad thing"? Not intrinsically. Is it a sign that you should re-examine your design of the classes? Yes. Why is something that creates a Department modifying a Person object? Should you be implementing a ChangeManager method on Department instead? Maybe, maybe not. But it's a question worth asking.
It's not a problem as long as Person is not a struct : if it is, then the Manager property will return a copy of the Person, and you will be setting the FirstName property on that copy, not on the department's Manager. But anyway, the compiler would scream if you tried to do that...
It's a question of OOP purity.
Not all pieces of code should be pure OOP. It's a matter of project complexity, number of programmers involved, maintainability, etc.
Your example is very simple, and that's why you can read so many opinions
It is sometimes hard to illustrate the advantages of OOP with simple examples.
Anyway, my thoughts:
It smells.
The line of code that really bothers me is
deathStar.Manager.FirstName = "Lord";
It can easily change to something like
deathStar.Manager.Address.City.Name = "Paris"
So in one line of code you see 4 classes in use! This makes a very strong assumption that the coupling of all 4 classes remains the same. In other words, it keeps the classes highly coupled.
You can resolve this by working with interfaces rather than concrete classes, and you can adopt the "Tell don't ask" guideline (Yahoo search; yes, Yahoo).
Here's a nice PDF that discusses OOP and refactoring (in Java, but the ideas are understood easily), see "Transitive coupling" section.
I think this is one of the reasons people tout functional languages so much - no "side effects". I don't think there is anything technically wrong with this, but it can make maintenance very difficult. To paraphrase Jurrasic Park, "...just because you can do something, doesn't mean you should!"
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);