diff --git a/.gitignore b/.gitignore
index 4a3a6d3..6c1ac87 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,9 @@
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
+# User-spacific editor config
+.editorconfig
+
# User-specific files
*.rsuser
*.suo
diff --git a/MCTG/MCTGApp/MCTGApp.csproj b/MCTG/MCTGApp/MCTGApp.csproj
index f184388..79a52db 100644
--- a/MCTG/MCTGApp/MCTGApp.csproj
+++ b/MCTG/MCTGApp/MCTGApp.csproj
@@ -7,6 +7,10 @@
enable
+
+
+
+
diff --git a/MCTG/MCTGApp/Program.cs b/MCTG/MCTGApp/Program.cs
index eb783ba..021e938 100644
--- a/MCTG/MCTGApp/Program.cs
+++ b/MCTG/MCTGApp/Program.cs
@@ -8,6 +8,7 @@ Console.WriteLine("Hello, World!\n");
// TESTS:
+// tests on Recipe class
BaseItem r1 = new Recipe("A recipe...");
r1.DisplayItem();
@@ -16,6 +17,7 @@ r1.DisplayDescription();
Console.WriteLine();
+// tests on RecipeCollection class
RecipeCollection rc = new RecipeCollection("A recipe collection...");
for (uint i = 0; i < 10; i++)
{
@@ -24,16 +26,24 @@ for (uint i = 0; i < 10; i++)
try // test overload of [] operator
{
- rc[1003].DisplayItem();
- rc[2003].DisplayItem(); // incorrect index
+ rc[2].DisplayId();
+ rc.GetById(1002);
}
catch (ArgumentNullException)
{
Console.Error.WriteLine("An index are incorrect!\n");
}
+// test of multiple params constructor
+RecipeCollection rc2 = new RecipeCollection(
+ new Recipe(),
+ new Recipe(),
+ new Recipe(),
+ new Recipe(),
+ new Recipe());
-foreach (Recipe r in rc.Collection)
+// test of Enumerable property
+foreach (Recipe r in rc2)
{
r.DisplayId();
r.DisplayDescription();
diff --git a/MCTG/MCTGLib/BaseItem.cs b/MCTG/MCTGLib/BaseItem.cs
index 36a653c..f031d66 100644
--- a/MCTG/MCTGLib/BaseItem.cs
+++ b/MCTG/MCTGLib/BaseItem.cs
@@ -1,5 +1,6 @@
using System;
+using System.ComponentModel;
namespace Model
{
@@ -7,24 +8,29 @@ namespace Model
/// Define the base structure of any Items.
/// An Item can be identifed and have a short description. It can also be displayed.
///
- public abstract class BaseItem : IDisplayable
+ public abstract class BaseItem : IDisplayable, IEquatable
{
///
/// The identifier of an Item.
/// The first number correspond to the typs of the Item.
///
- public uint Id { get; }
+ virtual public uint Id
+ {
+ get => _id;
+ init => _id = value;
+ }
+ protected uint _id;
+
///
/// A short description of the Item. Useful to know what this Item stand for.
///
public string Description { get; set; }
+
-
- protected BaseItem(uint id, string description = "")
+ protected BaseItem(uint id, string description="Any Item.")
{
- Id = id;
- Description = description;
+ Id = id; Description = description;
}
@@ -52,5 +58,28 @@ namespace Model
{
Console.WriteLine(this.ToString());
}
+
+ // IEquatable implementation
+ public bool Equals(BaseItem? other)
+ {
+ if (other != null)
+ return this.Id.Equals(other.Id);
+
+ return false;
+ }
+
+ public override bool Equals(object? obj)
+ {
+ BaseItem? baseItem = obj as BaseItem;
+ if (baseItem == null) return false;
+ if (baseItem == this) return true;
+
+ return this.Id.Equals(baseItem.Id);
+ }
+
+ public override int GetHashCode()
+ {
+ return this.Id.GetHashCode();
+ }
}
}
diff --git a/MCTG/MCTGLib/Recipe.cs b/MCTG/MCTGLib/Recipe.cs
index 0e6611f..2ab5420 100644
--- a/MCTG/MCTGLib/Recipe.cs
+++ b/MCTG/MCTGLib/Recipe.cs
@@ -5,35 +5,68 @@ namespace Model
{
///
/// A Recipe is a description of step and maybe some techniques, with an ingredient list to make a meal.
- /// It is instantiated with a new unique four digit id, where the first one is 1.
+ /// It is instantiated with a new unique id, where the first number is 1.
///
public class Recipe : BaseItem
{
- ///
- /// This static atrribute stand for the creation of a new id. It is incremented each time a new Recipe is instantiated.
- ///
- public static uint idIterator = 0;
+ #region Private Attributes
+
+ private static uint _idCreator = 0; // stand for the creation of a new id. It is incremented each time a new Recipe is instantiated.
+ private string title = "";
+
+ #endregion
+
+ #region Public Properties
///
/// The title of the recipe.
///
- public string Title { get; set; }
+ public string Title
+ {
+ get => title;
+ set
+ {
+ title = value;
+ if (string.IsNullOrEmpty(title)) title = $"Recipe n{this.Id}";
+ }
+ }
///
/// All the details about the preparation of the meal.
///
public string Preparation { get; set; }
+ #endregion
- public Recipe(string description = "", string title = "", string preparation = "")
- : base(idIterator+1000, description)
+ #region Constructors
+
+ public Recipe(string title="", string preparation="")
+ : base(ComputeId(), "A recipe.")
{
- if (idIterator == 1000) throw new OverflowException("id has reach the maximum value.");
Title = title;
Preparation = preparation;
- idIterator++;
}
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Processi the unique identificator of an Item. The identificator is calculated to put the number representing
+ /// the type of item before the number of its number in its type.
+ ///
+ private static uint ComputeId()
+ {
+ uint dec = 0, id = _idCreator;
+ while ((_idCreator / (Math.Pow(10, dec)) > 10)) dec++;
+ id += 1 * (uint)(Math.Pow(10, dec));
+
+ return id;
+ }
+
+ #endregion
+
+ #region Public Methods
public override string ToString()
{
@@ -43,5 +76,7 @@ namespace Model
$"\t.Description - {Description}\n" +
$"______\n\n";
}
+
+ #endregion
}
}
diff --git a/MCTG/MCTGLib/RecipeCollection.cs b/MCTG/MCTGLib/RecipeCollection.cs
index 594ae91..f93227d 100644
--- a/MCTG/MCTGLib/RecipeCollection.cs
+++ b/MCTG/MCTGLib/RecipeCollection.cs
@@ -1,38 +1,66 @@
using System;
+using System.Collections;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
namespace Model
{
///
/// A Recipe collection is a group of recipe.
- /// It is instantiated with a new unique four digit id, where the first one is 2.
+ /// It is instantiated with a new unique id, where the first number is 2.
///
- public class RecipeCollection : BaseItem
+ public class RecipeCollection : BaseItem, ICollection
{
- ///
- /// This static atrribute stand for the creation of a new id. It is incremented each time a new RecipeCollection is instantiated.
- ///
- private static uint idIterator = 0;
+ #region Private Attributes
+
+ private const int CAT_ITEM = 2; // the first number of the item full id : the item category.
+ private static uint _idCreator = 0; // stand for the creation of a new id. It is incremented each time a new Recipe is instantiated.
+ private ICollection _recipes = new List(); // main composent of this class.
+
+ #endregion
- ///
- /// The main composent of a RecipeCollection. This contain the Recipes included in this collection.
- ///
- public List Collection { get; set; }
+ #region Public Properties
+ #region ICollection Implementation
- public RecipeCollection(string description = "", List? collection = null)
- : base(idIterator + 2000, description)
+ public int Count => _recipes.Count;
+ public bool IsReadOnly => false;
+
+ #endregion
+ #endregion
+
+ #region Constructors
+
+ public RecipeCollection(string description="A recipe collection.")
+ : base(ComputeId(), description)
+ { }
+
+ public RecipeCollection(params Recipe[] recipes)
+ : base(ComputeId())
{
- if (idIterator == 1000) throw new OverflowException("id has reach the maximum value.");
+ _recipes.CopyTo(recipes, 0);
+ }
+
+ #endregion
- if (collection == null)
- Collection = new List();
- else
- Collection = collection;
+ #region Private Methods
- idIterator++;
+ ///
+ /// Processi the unique identificator of an Item. The identificator is calculated to put the number representing
+ /// the type of item before the number of its number in its type.
+ ///
+ private static uint ComputeId()
+ {
+ uint dec = 0, id = _idCreator;
+ while ((_idCreator / (Math.Pow(10, dec)) > 10)) dec++;
+ id += CAT_ITEM * (uint)(Math.Pow(10, dec));
+
+ return id;
}
+ #endregion
+
+ #region Public Methods
public override string ToString()
{
@@ -43,22 +71,66 @@ namespace Model
$"______\n\n";
}
+ public Recipe GetById(uint id)
+ {
+ if (this._recipes is not List)
+ throw new InvalidCastException("Need to verify the type of the private attribute '_recipes'.");
+
+ return (this._recipes as List).Find(x => x.Id.Equals(Id));
+ }
+
+ #region ICollection Implementation
+
+ public void Add(Recipe item)
+ {
+ _recipes.Add(item);
+ }
+
+ public void Clear()
+ {
+ _recipes.Clear();
+ }
+
+ public bool Contains(Recipe item)
+ {
+ return _recipes.Contains(item);
+ }
+
+ public void CopyTo(Recipe[] array, int arrayIndex)
+ {
+ _recipes.CopyTo(array, arrayIndex);
+ }
+
+ public bool Remove(Recipe item)
+ {
+ return _recipes.Remove(item);
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return _recipes.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _recipes.GetEnumerator();
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators Overloading
+
///
/// Overload the [] operator to access the Recipe directly without passing by the Collection.
/// It use the identifier of the Recipe to get the item.
///
/// The id of the Recipe
///
- public Recipe this[uint id]
+ public Recipe this[Index id]
{
- get
- {
- foreach (Recipe r in this.Collection)
- {
- if (r.Id == id) return r;
- }
- throw new ArgumentNullException("The id given dosen't correspond to any recipes in the collection.");
- }
+ get => this.ElementAt(id);
}
///
@@ -69,7 +141,7 @@ namespace Model
/// The recipe collection where the recipe is added.
public static RecipeCollection operator + (RecipeCollection coll, Recipe ri)
{
- coll.Collection.Add(ri); return coll;
+ coll.Add(ri); return coll;
}
///
@@ -80,7 +152,9 @@ namespace Model
/// The recipe collection where the recipe is removed.
public static RecipeCollection operator - (RecipeCollection coll, Recipe ri)
{
- coll.Collection.Remove(ri); return coll;
+ coll.Remove(ri); return coll;
}
+
+ #endregion
}
}