⚗️ try making the RecipeCollection act like a real collection
continuous-integration/drone/push Build is passing Details

pull/24/head
Alexandre Agostinho 2 years ago
parent 9b0015d3c4
commit fa25dbf757

3
.gitignore vendored

@ -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

@ -7,6 +7,10 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Include="..\.editorconfig" Link=".editorconfig" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MCTGLib\MCTGLib.csproj" />
</ItemGroup>

@ -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();

@ -1,5 +1,6 @@

using System;
using System.ComponentModel;
namespace Model
{
@ -7,13 +8,19 @@ namespace Model
/// Define the base structure of any Items.<br/>
/// An Item can be identifed and have a short description. It can also be displayed.
/// </summary>
public abstract class BaseItem : IDisplayable
public abstract class BaseItem : IDisplayable, IEquatable<BaseItem>
{
/// <summary>
/// The identifier of an Item.<br/>
/// The first number correspond to the typs of the Item.
/// </summary>
public uint Id { get; }
virtual public uint Id
{
get => _id;
init => _id = value;
}
protected uint _id;
/// <summary>
/// A short description of the Item. Useful to know what this Item stand for.
@ -21,10 +28,9 @@ namespace Model
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<BaseItem> 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();
}
}
}

@ -5,35 +5,68 @@ namespace Model
{
/// <summary>
/// A Recipe is a description of step and maybe some techniques, with an ingredient list to make a meal.<br/>
/// 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.
/// </summary>
public class Recipe : BaseItem
{
/// <summary>
/// This static atrribute stand for the creation of a new id. It is incremented each time a new Recipe is instantiated.
/// </summary>
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
/// <summary>
/// The title of the recipe.
/// </summary>
public string Title { get; set; }
public string Title
{
get => title;
set
{
title = value;
if (string.IsNullOrEmpty(title)) title = $"Recipe n{this.Id}";
}
}
/// <summary>
/// All the details about the preparation of the meal.
/// </summary>
public string Preparation { get; set; }
#endregion
#region Constructors
public Recipe(string description = "", string title = "", string preparation = "")
: base(idIterator+1000, description)
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
/// <summary>
/// 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.
/// </summary>
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
}
}

@ -1,38 +1,66 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Model
{
/// <summary>
/// A Recipe collection is a group of recipe.<br/>
/// 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.
/// </summary>
public class RecipeCollection : BaseItem
public class RecipeCollection : BaseItem, ICollection<Recipe>
{
/// <summary>
/// This static atrribute stand for the creation of a new id. It is incremented each time a new RecipeCollection is instantiated.
/// </summary>
private static uint idIterator = 0;
#region Private Attributes
/// <summary>
/// The main composent of a RecipeCollection. This contain the Recipes included in this collection.
/// </summary>
public List<Recipe> Collection { get; set; }
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<Recipe> _recipes = new List<Recipe>(); // main composent of this class.
#endregion
#region Public Properties
#region ICollection Implementation
public int Count => _recipes.Count;
public bool IsReadOnly => false;
public RecipeCollection(string description = "", List<Recipe>? collection = null)
: base(idIterator + 2000, description)
#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
#region Private Methods
if (collection == null)
Collection = new List<Recipe>();
else
Collection = collection;
/// <summary>
/// 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.
/// </summary>
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));
idIterator++;
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<Recipe>)
throw new InvalidCastException("Need to verify the type of the private attribute '_recipes'.");
return (this._recipes as List<Recipe>).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<Recipe> GetEnumerator()
{
return _recipes.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _recipes.GetEnumerator();
}
#endregion
#endregion
#region Operators Overloading
/// <summary>
/// Overload the [] operator to access the Recipe directly without passing by the Collection.<br/>
/// It use the identifier of the Recipe to get the item.
/// </summary>
/// <param name="id">The id of the Recipe</param>
/// <returns></returns>
public Recipe this[uint id]
{
get
{
foreach (Recipe r in this.Collection)
public Recipe this[Index id]
{
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);
}
/// <summary>
@ -69,7 +141,7 @@ namespace Model
/// <returns>The recipe collection where the recipe is added.</returns>
public static RecipeCollection operator + (RecipeCollection coll, Recipe ri)
{
coll.Collection.Add(ri); return coll;
coll.Add(ri); return coll;
}
/// <summary>
@ -80,7 +152,9 @@ namespace Model
/// <returns>The recipe collection where the recipe is removed.</returns>
public static RecipeCollection operator - (RecipeCollection coll, Recipe ri)
{
coll.Collection.Remove(ri); return coll;
coll.Remove(ri); return coll;
}
#endregion
}
}

Loading…
Cancel
Save