samedi 19 septembre 2015

C# Composite with custom comparer

I have problem with implementing custom comparer in Composite C#. I would like to pass custom comparer my Composite object.

Here is IComponent interface:

namespace composite
{
    /// <summary>
    /// The Component interface.
    /// </summary>
    /// <typeparam name="T">
    /// </typeparam>
    public interface IComponent<T>
    {
        /// <summary>
        /// The add.
        /// </summary>
        /// <param name="component">
        /// The item.
        /// </param>
        void Add(IComponent<T> component);

        /// <summary>
        /// The find.
        /// </summary>
        /// <param name="item">
        /// The item.
        /// </param>
        /// <returns>
        /// The <see cref="IComponent"/>.
        /// </returns>
        IComponent<T> Find(T item);

        /// <summary>
        /// The remove.
        /// </summary>
        /// <param name="item">
        /// The item.
        /// </param>
        /// <returns>
        /// The <see cref="IComponent"/>.
        /// </returns>
        IComponent<T> Remove(T item);

        /// <summary>
        /// The dsiplay.
        /// </summary>
        /// <param name="depth">
        /// The depth.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        string Display(int depth);

        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        string Name { get; set; }
    }
}

For Component a Composite object I´m using the same interface.

Composite (my Collection of Components)

namespace composite
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Text;

    /// <summary>
    /// The composite.
    /// </summary>
    /// <typeparam name="T">
    /// </typeparam>
    public class Composite<T> : IComponent<T>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Composite{T}"/> class.
        /// </summary>
        /// <param name="name">
        /// The name.
        /// </param>
        public Composite(string name)
        {
            this.Name = name;
            this.holder = null;
            this.components = new List<IComponent<T>>();
        }


        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// The components.
        /// </summary>
        private ICollection<IComponent<T>> components;

        /// <summary>
        /// The helper.
        /// </summary>
        private IComponent<T> holder;

        /// <summary>
        /// The add.
        /// </summary>
        /// <param name="component">
        /// The component.
        /// </param>
        public void Add(IComponent<T> component)
        {
            this.components.Add(component);
        }

        /// <summary>
        /// The find.
        /// </summary>
        /// <param name="item">
        /// The item.
        /// </param>
        /// <returns>
        /// The <see cref="IComponent"/>.
        /// </returns>
        public IComponent<T> Find(T item)
        {
            this.holder = this;
            if (item.Equals(this.Name))
            {
                return this;
            }

            IComponent<T> found = null;

            //this.components.Select(s => s.Name == item)

            foreach (IComponent<T> component in this.components)
            {
                found = component.Find(item);
                if (found != null)
                {
                    break;
                }
            }

            return found;
        }

        /// <summary>
        /// The remove.
        /// </summary>
        /// <param name="item">
        /// The item.
        /// </param>
        /// <returns>
        /// The <see cref="IComponent"/>.
        /// </returns>
        public IComponent<T> Remove(T item)
        {
            this.holder = this;
            IComponent<T> p = holder.Find(item);
            if (this.holder != null)
            {
                (this.holder as Composite<T>).components.Remove(p);
                return this.holder;
            }
            else
            {
                return this;
            }
        }

        //public IEnumerable<IComponent<T>> Dsiplay(int depth)


        public string Display(int depth)
        {
            StringBuilder s = new StringBuilder();
            s.Append("set " + this.Name + " length :" + this.components.Count + "\n");
            foreach (IComponent<T> component in components)
            {
                s.Append(component.Display(depth + 2));
            }

            return s.ToString();
        }

    }
}

Component:

namespace composite
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// The component.
    /// </summary>
    /// <typeparam name="T">
    /// </typeparam>
    public class Component<T> : IComponent<T>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Component{T}"/> class.
        /// </summary>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <param name="myComparer"></param>
        public Component(string name)
        {
            this.Name = name;
        }

        public string Display(int depth)
        {
            return new string('-', depth) + this.Name + "\n";
        }

        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Gets the my comparer.
        /// </summary>
        public IComparer<T> MyComparer { get; private set; }

        //public IComparer<T> myComparer { set; }

        /// <summary>
        /// The add.
        /// </summary>
        /// <param name="item">
        /// The item.
        /// </param>
        /// <exception cref="NotImplementedException">
        /// Neimplementovano
        /// </exception>
        public void Add(IComponent<T> item)
        { 
            throw new NotImplementedException();
        }

        /// <summary>
        /// The find.
        /// </summary>
        /// <param name="item">
        /// The item.
        /// </param>
        /// <returns>
        /// The <see cref="IComponent"/>.
        /// </returns>
        public IComponent<T> Find(T item)
        {

            //Here I want to use comparer object, instead of Equals
            //Something like this:

            //return MyComparer.Compare( ... ) == 0 ? this : null;

            return item.Equals(this.Name) ? this : null;
        }

        /// <summary>
        /// The remove.
        /// </summary>
        /// <param name="item">
        /// The item.
        /// </param>
        /// <returns>
        /// The <see cref="IComponent"/>.
        /// </returns>
        /// <exception cref="NotImplementedException">
        /// </exception>
        public IComponent<T> Remove(T item)
        {
            throw new NotImplementedException();
        }
    }
}

And finally my main function:

namespace composite
{
    class Program
    {
        static void Main(string[] args)
        {
            //Creating custom comparer and pass to the constructor composite?
            IComparer<string> myComparer = new ...


            IComponent<string> comp1 = new Component<string>("Komponenta 1");
            IComponent<string> comp2 = new Component<string>("Komponenta 2");
            IComponent<string> comp3 = new Component<string>("Komponenta 3");
            IComponent<string> comp4 = new Component<string>("Komponenta 4");
            IComponent<string> comp5 = new Component<string>("Komponenta 5");

            IComponent<string> composite = new Composite<string>("Composite 1");

            IComponent<string> composite2 = new Composite<string>("Composite 2");

            composite.Add(comp1);
            composite.Add(comp2);
            composite.Add(comp3);
            composite.Add(comp4);
            composite.Add(comp5);

            composite2.Add(comp1);
            composite2.Add(comp2);
            composite2.Add(comp3);
            composite2.Add(comp4);
            composite2.Add(comp5);

            composite.Add(composite2);

            Console.Write(composite.Display(0));
        }
    }
}

Can you help me with implement custom comparer and pass to Find method? Is it good way or not?

Very thanks

Aucun commentaire:

Enregistrer un commentaire