How is the Memento Pattern implemented in C#4? - c#

The Memento Pattern itself seems pretty straight forward. I'm considering implementing the same as the wikipedia example, but before I do are there any language features of C# that make it easier to implement or use?

One obvious feature would be generics, implementing an generic memento will allow you to use it for any object you want.
Many examples that you will see will use a string (including all those currently among the replies to this question) as state which is a problem since it's one of the few types in .NET which are immutable.
When dealing with mutable objects (like any reference type with a setter-property) you have to remember though that when you save the memento you need to create a deepcopy of the object. Otherwise whenever you change your original object you will change your memento.
You could do this by using a serializer like protobuf-net or json.net since they don't require you to mark your objects with serializable attribute like the normal .net serialization mechanism does.
Codeproject have few articles about generic memento implementations, but they tend to skip the deepcopy part:
Generic Memento Pattern for Undo-Redo in C#
Memento Design Pattern

I'm not aware of any already built-in way to support Memento pattern.
I see a couple of implementations by using .NET Mock frameworks, where in practise a clone of the object is created and can be field with a data, but I consider it kind of overhead.
The use Memento patter on Undo/Redo usually, probably you too. In this case, it's better to have as less data on Undo/Redo stack as possible, so the custom undoable object is something that I would go for.
Hope this helps.

There is one thing that will make this pattern marginally quicker to write in C# and that is that any state fields can be declared as public readonly so you don't need properties or 'get' methods to access them.
Here is a straight conversion with public readonly included.
class Originator
{
private string state;
// The class could also contain additional data that is not part of the
// state saved in the memento.
public void Set(string state)
{
Console.WriteLine("Originator: Setting state to " + state);
this.state = state;
}
public Memento SaveToMemento()
{
Console.WriteLine("Originator: Saving to Memento.");
return new Memento(state);
}
public void RestoreFromMemento(Memento memento)
{
state = memento.SavedState;
Console.WriteLine("Originator: State after restoring from Memento: " + state);
}
public class Memento
{
public readonly string SavedState;
public Memento(string stateToSave)
{
SavedState = stateToSave;
}
}
}
class Caretaker
{
static void Main(string[] args)
{
List<Originator.Memento> savedStates = new List<Originator.Memento>();
Originator originator = new Originator();
originator.Set("State1");
originator.Set("State2");
savedStates.Add(originator.SaveToMemento());
originator.Set("State3");
// We can request multiple mementos, and choose which one to roll back to.
savedStates.Add(originator.SaveToMemento());
originator.Set("State4");
originator.RestoreFromMemento(savedStates[1]);
}
}

I've found one using Generics here:
#region Originator
public class Originator<T>
{
#region Properties
public T State { get; set; }
#endregion
#region Methods
/// <summary>
/// Creates a new memento to hold the current
/// state
/// </summary>
/// <returns>The created memento</returns>
public Memento<T> SaveMemento()
{
return (new Memento<T>(State));
}
/// <summary>
/// Restores the state which is saved in the given memento
/// </summary>
/// <param name="memento">The given memento</param>
public void RestoreMemento(Memento<T> memento)
{
State = memento.State;
}
#endregion
}
#endregion
#region Memento
public class Memento<T>
{
#region Properties
public T State { get; private set; }
#endregion
#region Ctor
/// <summary>
/// Construct a new memento object with the
/// given state
/// </summary>
/// <param name="state">The given state</param>
public Memento(T state)
{
State = state;
}
#endregion
}
#endregion
#region Caretaker
public class Caretaker<T>
{
#region Properties
public Memento<T> Memento { get; set; }
#endregion
}
#endregion
#region Originator
public class Originator<T>
{
#region Properties
public T State { get; set; }
#endregion
#region Methods
/// <summary>
/// Creates a new memento to hold the current
/// state
/// </summary>
/// <returns>The created memento</returns>
public Memento<T> SaveMemento()
{
return (new Memento<T>(State));
}
/// <summary>
/// Restores the state which is saved in the given memento
/// </summary>
/// <param name="memento">The given memento</param>
public void RestoreMemento(Memento<T> memento)
{
State = memento.State;
}
#endregion
}
#endregion
#region Memento
public class Memento<T>
{
#region Properties
public T State { get; private set; }
#endregion
#region Ctor
/// <summary>
/// Construct a new memento object with the
/// given state
/// </summary>
/// <param name="state">The given state</param>
public Memento(T state)
{
State = state;
}
#endregion
}
#endregion
#region Caretaker
public class Caretaker<T>
{
#region Properties
public Memento<T> Memento { get; set; }
#endregion
}
#endregion
Used like this:
Originator<string> org = new Originator<string>();
org.State = "Old State";
// Store internal state in the caretaker object
Caretaker<string> caretaker = new Caretaker<string>();
caretaker.Memento = org.SaveMemento();
Console.WriteLine("This is the old state: {0}", org.State);
org.State = "New state";
Console.WriteLine("This is the new state: {0}", org.State);
// Restore saved state from the caretaker
org.RestoreMemento(caretaker.Memento);
Console.WriteLine("Old state was restored: {0}", org.State);
// Wait for user
Console.Read();
As #Simon Skov Boisen mentions this will only work for immutable data and requires a deep copy.

Related

Is there any reason to use very simple properties over fields?

I currently have this code written:
public class General
{
/// <summary>
/// Private variables.
/// </summary>
private const float fVersion = 1.3f;
private static bool bMonitoring = false;
/// <summary>
/// Retrieves the current version of the application.
/// </summary>
public static float Version
{
get
{
return fVersion;
}
}
/// <summary>
/// Are we monitoring performance?
/// </summary>
public static bool Monitoring
{
get
{
return bMonitoring;
}
set
{
bMonitoring = value;
}
}
}
In case I check for General.bMonitoring or General.Version often (maybe.. over 100 times a second!) and really care about performance: is it good practice to leave my class written like that, or should I simply delete these properties and make the fields public?
In this case if you aren't going to add some logic to the getter or setter then I would use static fields. Performance will be the same.
But if later you need extra logic when you set ot get values then it preffer to use properties because it allows for versioning and it gives you Encapsulation according to OOP principles. Don't care about performance
For Monitoring property you can use Auto-Implemented Property like
public static bool Monitoring { get; set; }
but in this case you need to implement a static constructor (thanks to #Mafii)
static General()
{
Monitoring = false;
}
or if you use C# 6.0 then just:
public static bool Monitoring { get; set; } = false;
Don't worry about performance. Property access is (and should be) very fast and compiler may inline them.
Property is preferred over field not because of performance, but because encapsulation and it will really helps when later you need for example checking or make property computed.
More by Jon Skeet http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx

Serializing a collection and comply to Code Analysis

While running Code Analysis on an existing project I came across the messages Do not expose generic lists and Collection properties should be read only.
However, this class is used to read/write from/to an xml configuration file.
Is it possible to make this class comply to CA1002 and CA2227 or do I have to suppress these rules for XML-related classes (there are a lot of them in the project)?
EDIT
Changing List<string> to Collection<string> solved CA1002.
Still no clue on how to solve CA2227 and still be able to (de)serialize the whole thing.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
/// <summary>
/// Class containing the Configuration Storage
/// </summary>
[XmlRoot("Configuration")]
public class ConfigurationStorage
{
/// <summary>
/// Gets or sets the list of executers.
/// </summary>
[XmlArray("Executers")]
[XmlArrayItem("Executer")]
public Collection<string> Executers { get; set; }
/// <summary>
/// Gets or sets the list of IPG prefixes.
/// </summary>
[XmlArray("IpgPrefixes")]
[XmlArrayItem("IpgPrefix")]
public Collection<string> IpgPrefixes { get; set; }
}
Reading the xml-file:
public static ConfigurationStorage LoadConfiguration()
{
if (File.Exists(ConfigFile))
{
try
{
using (TextReader r = new StreamReader(ConfigFile))
{
var s = new XmlSerializer(typeof(ConfigurationStorage));
var config = (ConfigurationStorage)s.Deserialize(r);
return config;
}
}
catch (InvalidOperationException invalidOperationException)
{
throw new StorageException(
"An error occurred while deserializing the configuration XML file.", invalidOperationException);
}
}
}
How about:
/// <summary>
/// Class containing the Configuration Storage
/// </summary>
[XmlRoot("Configuration")]
public class ConfigurationStorage {
/// <summary>
/// Gets or sets the list of executers.
/// </summary>
[XmlArray("Executers")]
[XmlArrayItem("Executer")]
public Collection<string> Executers { get; private set; }
/// <summary>
/// Gets or sets the list of IPG prefixes.
/// </summary>
[XmlArray("IpgPrefixes")]
[XmlArrayItem("IpgPrefix")]
public Collection<string> IpgPrefixes { get; private set; }
public ConfigurationStorage() {
Executers = new Collection<string>();
IpgPrefixes = new Collection<string>();
}
}
This will still work for xml serialization/deserialization.
If you read the documentation on MSDN, you see a note:
The XmlSerializer gives special treatment to classes that implement
IEnumerable or ICollection. A class that implements IEnumerable must
implement a public Add method that takes a single parameter. The Add
method's parameter must be of the same type as is returned from the
Current property on the value returned from GetEnumerator, or one of
that type's bases. A class that implements ICollection (such as
CollectionBase) in addition to IEnumerable must have a public Item
indexed property (indexer in C#) that takes an integer, and it must
have a public Count property of type integer. The parameter to the Add
method must be the same type as is returned from the Item property, or
one of that type's bases. For classes that implement ICollection,
values to be serialized are retrieved from the indexed Item property,
not by calling GetEnumerator.
So, I think, if you fall in line with this special treatment, you'll have better code that works with XmlSerializer, doesn't use a legacy namespace, and satisfies Code Analysis warnings in the right way, rather than exploiting an oversight in the rule.
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
/// <summary>
/// Class containing the Configuration Storage
/// </summary>
[XmlRoot("Configuration")]
public class ConfigurationStorage
{
// The executers.
private readonly ICollection<string> executers = new List<string>();
// The IPG prefixes.
private readonly ICollection<string> ipgPrefixes = new List<string>();
/// <summary>
/// Gets the list of executers.
/// </summary>
[XmlArray("Executers")]
[XmlArrayItem("Executer")]
public ICollection<string> Executers
{
get
{
return this.executers;
}
}
/// <summary>
/// Gets the list of IPG prefixes.
/// </summary>
[XmlArray("IpgPrefixes")]
[XmlArrayItem("IpgPrefix")]
public ICollection<string> IpgPrefixes
{
get
{
return this.ipgPrefixes;
}
}
}

Is the Strategy design pattern suitable for logic based on string comparisons?

As of now my code has multiple if else statements branching, depending upon the value of a string. i.e.
if(input == "condition1")
{
// Some logic
}
else if(input =="condition1")
{
// Some other logic
}
I'm planning to use the Strategy Pattern. Is this the right approach? If yes, how can I create the correct Concrete Strategy object depending on the condition?
Thanks
In the code example you have provided, Strategy is not going to get you away from the if conditions you already have. You would end up needing a Factory to create your strategy objects as follows:
static class StrategyFactory
{
static IStrategy CreateStrategy(string input)
{
if (input == "condition1")
{
return new StrategyForCondition1();
}
else if (input == "condition2")
{
return new StrategyForCondition2();
}
}
}
This is why I would not recommend Strategy for your case.
A very elegant alternative solution is to use a Dictionary where the key is the input string value and the Action is the contents of the if statement:
var actions = new Dictionary<string, Action>
{
{"condition1", () => Console.WriteLine("condition1")},
{"condition2", NameOfMethodThatHandlesCondition2}
};
Now, the beauty of this solution is that you use it with only 1 line of code:
actions[input];
See examples here: http://elegantcode.com/2009/01/10/refactoring-a-switch-statement/
One issue in your code sample is that you are comparing to a string... which could be any possible value. If possible, create an enum instead that represents all possible conditions. This will prevent coming up against a string value that you are not anticipating.
Here is a great site with some really good examples of different Pattern types in C#.
Strategy Design Patterns in C# and VB
// Strategy pattern -- Structural example
using System;
namespace DoFactory.GangOfFour.Strategy.Structural
{
/// <summary>
/// MainApp startup class for Structural
/// Strategy Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
Context context;
// Three contexts following different strategies
context = new Context(new ConcreteStrategyA());
context.ContextInterface();
context = new Context(new ConcreteStrategyB());
context.ContextInterface();
context = new Context(new ConcreteStrategyC());
context.ContextInterface();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Strategy' abstract class
/// </summary>
abstract class Strategy
{
public abstract void AlgorithmInterface();
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class ConcreteStrategyA : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("Called ConcreteStrategyA.AlgorithmInterface()");
}
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class ConcreteStrategyB : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("Called ConcreteStrategyB.AlgorithmInterface()");
}
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class ConcreteStrategyC : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("Called ConcreteStrategyC.AlgorithmInterface()");
}
}
/// <summary>
/// The 'Context' class
/// </summary>
class Context
{
private Strategy _strategy;
// Constructor
public Context(Strategy strategy)
{
this._strategy = strategy;
}
public void ContextInterface()
{
_strategy.AlgorithmInterface();
}
}
}
Output
Called ConcreteStrategyA.AlgorithmInterface()
Called ConcreteStrategyB.AlgorithmInterface()
Called ConcreteStrategyC.AlgorithmInterface()
Why not just use a switch?
switch (input) {
case "condition1":
// do stuff
break;
case "condition2":
// do stuff....
break;
default:
// default stuff
break;
}
Or failing that use a Dictionary<string,Action>
var actions=new Dictionary<string,Action> { { "condition1", () => {code}}, {"condition2",) => {code}};
Then..
if (actions.ContainsKey(input)) actions[input]();

C# - Intercepting property changes in subclasses

I'm in the process of creating a framework in which I provide the base class and the implementers of the framework will inherit from the base class and provide additional properties and methods. In the base class, I would like to have a way of observing when a property value is changed. The property can be from the base class or in any of the subclasses. I know that through reflection, I can determine the list of properties from any instance, but is there a way I can track the property changing value?
Here is a very simplistic example of what I am saying:
public class BaseClass
{
public string BaseClassProperty { get; set; }
public void DoSomethingWhenEitherPropertyGetsChanged()
{
}
}
public class SubClass : BaseClass
{
public string SubClassProperty { get; set; }
}
What can I do to have DoSomethingWhenEitherPropertyGetsChanged get executed when either of the properties has it's value changed.
You can use notifypropertyweaver for this purpose. It does exactly what you want. Here's a link:
notifypropertyweaver
From the open source home page:
Uses IL weaving (via http://www.mono-project.com/Cecil) to inject INotifyPropertyChanged code into properties.
No attributes required
No references required
No base class required
Supports .net 3.5, .net 4, Silverlight 3, Silverlight 4, Silverlight 5 and Windows Phone 7
Supports client profile mode
I would probably use Postsharp and create an inherited attribute injecting interception code into all public properties. Marking the attribute as inherited should also attach it to all subclasses automatically.
I wrote my own idea of your requirements, but I am not sure if it suits your needs. INotifyProperty changed is something you could also look into, but I don't really like it because it is like wiring up speghetti. Maybe this will give you some creative ideas, though.
What this does, is allow you to use ObservableObject as for all of your properties types. By doing this, each property will have an ObjectChanged event you can wire-up to. The con(s) are that you must initialize all of your properties in the constructor to prevent a NullReferenceException somewhere in your code.
This example uses three classes.
ObservableObject.cs
Employee.cs
Program.cs
ObservableObject.cs
//-----------------------------------------------------------------------------
// <copyright file="ObservableObject.cs" company="DCOM Productions">
// Copyright (c) DCOM Productions. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------
namespace PropertyChangedEventExample {
using System;
public class ObservableObject : Object {
/// <summary>
/// Expose the default constructor
/// </summary>
public ObservableObject() {
// No default implementation
}
private object m_Object = null;
/// <summary>
/// Base object
/// </summary>
public object Object {
get {
return m_Object;
}
set {
if (m_Object != value) {
m_Object = value;
OnObjectChanged(this, EventArgs.Empty);
}
}
}
/// <summary>
/// Triggered when the value of this object has changed.
/// </summary>
public event System.EventHandler<EventArgs> ObjectChanged;
/// <summary>
/// EventHandler wire-up
/// </summary>
protected virtual void OnObjectChanged(object sender, System.EventArgs e) {
if (ObjectChanged != null) {
ObjectChanged(sender, e);
}
}
/// <summary>
/// Gets the value
/// </summary>
public object Get() {
return this.Object;
}
/// <summary>
/// Sets the value
/// </summary>
public void Set(object value) {
this.Object = value;
}
}
}
Employee.cs
//-----------------------------------------------------------------------------
// <copyright file="Employee.cs" company="DCOM Productions">
// Copyright (c) DCOM Productions. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------
namespace PropertyChangedEventExample {
using System;
public class Employee {
/// <summary>
/// Expose default constructor
/// </summary>
public Employee() {
Name = new ObservableObject();
}
/// <summary>
/// Gets or sets the name
/// </summary>
public ObservableObject Name {
get;
set;
}
}
}
Program.cs
//-----------------------------------------------------------------------------
// <copyright file="Program.cs" company="DCOM Productions">
// Copyright (c) DCOM Productions. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------
namespace PropertyChangedEventExample {
using System;
class Program {
static void Main(string[] args) {
Employee employee = new Employee();
employee.Name.Set("David");
employee.Name.ObjectChanged += new EventHandler<EventArgs>(Name_ObjectChanged);
employee.Name.Set("Dave");
Console.ReadKey(true);
}
static void Name_ObjectChanged(object sender, EventArgs e) {
ObservableObject employee = sender as ObservableObject;
Console.WriteLine("Name changed to {0}", employee.Get());
}
}
}
Your best bet would be what CrisWue recommended and use postsharp or some other post-processor to inject the behavior in your properties. Other than that I think you would need to call DoSomethingWhenEitherPropertyGetsChanged() manually within your properties.
If you are creating a library that is consumed by people other than you or your organization, a post-processor may not be the right way to go as it adds the 3rd party tool as another requirement to their build process.

Fixing error: cannot reference a type through an expression

I'm developing a game. I want to have game entities each have their own Damage() function. When called, they will calculate how much damage they want to do:
public class CombatantGameModel : GameObjectModel
{
public int Health { get; set; }
/// <summary>
/// If the attack hits, how much damage does it do?
/// </summary>
/// <param name="randomSample">A random value from [0 .. 1]. Use to introduce randomness in the attack's damage.</param>
/// <returns>The amount of damage the attack does</returns>
public delegate int Damage(float randomSample);
public CombatantGameModel(GameObjectController controller) : base(controller) {}
}
public class CombatantGameObject : GameObjectController
{
private new readonly CombatantGameModel model;
public new virtual CombatantGameModel Model
{
get { return model; }
}
public CombatantGameObject()
{
model = new CombatantGameModel(this);
}
}
However, when I try to call that method, I get a compiler error:
/// <summary>
/// Calculates the results of an attack, and directly updates the GameObjects involved.
/// </summary>
/// <param name="attacker">The aggressor GameObject</param>
/// <param name="victim">The GameObject under assault</param>
public void ComputeAttackUpdate(CombatantGameObject attacker, CombatantGameObject victim)
{
if (worldQuery.IsColliding(attacker, victim, false))
{
victim.Model.Health -= attacker.Model.Damage((float) rand.NextDouble()); // error here
Debug.WriteLine(String.Format("{0} hits {1} for {2} damage", attacker, victim, attackTraits.Damage));
}
}
The error is:
'Damage': cannot reference a type
through an expression; try
'HWAlphaRelease.GameObject.CombatantGameModel.Damage'
instead
What am I doing wrong?
You need to associate a function with that delegate before you can invoke it.
You don't need a delegate here - with the code you have, you are better off having your Damage function as either an implementation of an interface, or have it declared as abstract (or virtual) in the base GameObjectModel class so that the derived classes can (or have to) override it.
You are actually declaring a nested delegate type named Damage, not an instance of that type. Think of it as the difference between a class an an instance of a class.
To actually use your delegate, you must declare a field, property or event to hold it.
For example:
// note that the delegate can be declared either in a class or outside of it.
public delegate int Damage(float randomSample);
public class CombatantGameModel /* ... */
{
/* ... */
public Damage DamageCalculator { get; set; }
}

Categories