using System; using System.Collections.Generic; namespace Inspectron.Settings { public class AdaptablePath : Path, IAdaptable, IDecoratable { /// /// Constructor /// Single object making up the path public AdaptablePath(T last) : base(last) { } /// /// Constructor /// Path as sequence of objects public AdaptablePath(IEnumerable path) : base(path) { } /// /// Constructor /// Path as collection of objects public AdaptablePath(ICollection path) : base(path) { } #region IAdaptable, IDecoratable, and Related Methods /// /// Gets an adapter of the specified type or null /// Adapter type /// Adapter of the specified type or null public object GetAdapter(Type type) { object adapter = Last.As(type); if (adapter != null) return adapter; if (type.IsAssignableFrom(GetType())) return this; return null; } /// /// Gets all decorators of the specified type /// Decorator type /// Enumeration of non-null decorators that are of the specified type. The enumeration may be empty. public IEnumerable GetDecorators(Type type) { foreach (object obj in Last.AsAll(type)) yield return obj; } // implement the following members as a convenience when extension methods aren't available /// /// Converts a reference to the given type by first trying a CLR cast, and then /// trying to get an adapter /// Desired type, must be ref type /// Converted reference for the given object or null public U As() where U : class { return Adapters.As(this); } /// /// Converts a reference to the given type by first trying a CLR cast, and then /// trying to get an adapter; if none is available, throws an AdaptationException /// Desired type, must be ref type /// Converted reference for the given object public U Cast() where U : class { return Adapters.Cast(this); } /// /// Returns whether the given reference can be converted to one of /// the desired type /// Adapter type, must be ref type /// True iff the given object can be converted public bool Is() where U : class { return Adapters.Is(this); } /// /// Returns an enumeration of all decorators that can convert a reference to the given type /// Decorator type, must be ref type /// Enumerable returning all decorators of the given type public IEnumerable AsAll() where U : class { return Adapters.AsAll(this); } #endregion /// /// Concatenates object with path /// Prefix object /// Optional path /// Concatenated path, with lhs as first object public static AdaptablePath operator +(T lhs, AdaptablePath rhs) { if (rhs == null) return new AdaptablePath(lhs); T[] path = new T[1 + rhs.Count]; path[0] = lhs; rhs.CopyTo(path, 1); return new AdaptablePath(path); } /// /// Concatenates path with object /// Optional path /// Suffix object /// Concatenated path, with rhs as last object public static AdaptablePath operator +(AdaptablePath lhs, T rhs) { if (lhs == null) return new AdaptablePath(rhs); T[] path = new T[lhs.Count + 1]; lhs.CopyTo(path, 0); path[lhs.Count] = rhs; return new AdaptablePath(path); } /// /// Concatenates 2 paths /// First path. Can be null. /// Second path. Can be null. /// Concatenated path, with rhs as prefix and lhs as suffix. Is null if both lhs and rhs are null. public static AdaptablePath operator +(AdaptablePath lhs, AdaptablePath rhs) { if (lhs == null) return rhs; if (rhs == null) return lhs; T[] path = new T[lhs.Count + rhs.Count]; lhs.CopyTo(path, 0); rhs.CopyTo(path, lhs.Count); return new AdaptablePath(path); } /// /// Converts from the path type to another type /// Desired type /// Item to convert /// Item converted to given type or null protected override U Convert(T item) { U u = item.As(); return u; } } }