164 lines
5.8 KiB
C#
164 lines
5.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Inspectron.Settings
|
|
{
|
|
public class AdaptablePath<T> : Path<T>, IAdaptable, IDecoratable
|
|
{
|
|
/// <summary>
|
|
/// Constructor</summary>
|
|
/// <param name="last">Single object making up the path</param>
|
|
public AdaptablePath(T last)
|
|
: base(last)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor</summary>
|
|
/// <param name="path">Path as sequence of objects</param>
|
|
public AdaptablePath(IEnumerable<T> path)
|
|
: base(path)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor</summary>
|
|
/// <param name="path">Path as collection of objects</param>
|
|
public AdaptablePath(ICollection<T> path)
|
|
: base(path)
|
|
{
|
|
}
|
|
|
|
#region IAdaptable, IDecoratable, and Related Methods
|
|
|
|
/// <summary>
|
|
/// Gets an adapter of the specified type or null</summary>
|
|
/// <param name="type">Adapter type</param>
|
|
/// <returns>Adapter of the specified type or null</returns>
|
|
public object GetAdapter(Type type)
|
|
{
|
|
object adapter = Last.As(type);
|
|
if (adapter != null)
|
|
return adapter;
|
|
|
|
if (type.IsAssignableFrom(GetType()))
|
|
return this;
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets all decorators of the specified type</summary>
|
|
/// <param name="type">Decorator type</param>
|
|
/// <returns>Enumeration of non-null decorators that are of the specified type. The enumeration may be empty.</returns>
|
|
public IEnumerable<object> 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
|
|
|
|
/// <summary>
|
|
/// Converts a reference to the given type by first trying a CLR cast, and then
|
|
/// trying to get an adapter</summary>
|
|
/// <typeparam name="U">Desired type, must be ref type</typeparam>
|
|
/// <returns>Converted reference for the given object or null</returns>
|
|
public U As<U>()
|
|
where U : class
|
|
{
|
|
return Adapters.As<U>(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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</summary>
|
|
/// <typeparam name="U">Desired type, must be ref type</typeparam>
|
|
/// <returns>Converted reference for the given object</returns>
|
|
public U Cast<U>() where U : class
|
|
{
|
|
return Adapters.Cast<U>(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns whether the given reference can be converted to one of
|
|
/// the desired type</summary>
|
|
/// <typeparam name="U">Adapter type, must be ref type</typeparam>
|
|
/// <returns>True iff the given object can be converted</returns>
|
|
public bool Is<U>()
|
|
where U : class
|
|
{
|
|
return Adapters.Is<U>(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns an enumeration of all decorators that can convert a reference to the given type</summary>
|
|
/// <typeparam name="U">Decorator type, must be ref type</typeparam>
|
|
/// <returns>Enumerable returning all decorators of the given type</returns>
|
|
public IEnumerable<U> AsAll<U>()
|
|
where U : class
|
|
{
|
|
return Adapters.AsAll<U>(this);
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Concatenates object with path</summary>
|
|
/// <param name="lhs">Prefix object</param>
|
|
/// <param name="rhs">Optional path</param>
|
|
/// <returns>Concatenated path, with lhs as first object</returns>
|
|
public static AdaptablePath<T> operator +(T lhs, AdaptablePath<T> rhs)
|
|
{
|
|
if (rhs == null)
|
|
return new AdaptablePath<T>(lhs);
|
|
T[] path = new T[1 + rhs.Count];
|
|
path[0] = lhs;
|
|
rhs.CopyTo(path, 1);
|
|
return new AdaptablePath<T>(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Concatenates path with object</summary>
|
|
/// <param name="lhs">Optional path</param>
|
|
/// <param name="rhs">Suffix object</param>
|
|
/// <returns>Concatenated path, with rhs as last object</returns>
|
|
public static AdaptablePath<T> operator +(AdaptablePath<T> lhs, T rhs)
|
|
{
|
|
if (lhs == null)
|
|
return new AdaptablePath<T>(rhs);
|
|
T[] path = new T[lhs.Count + 1];
|
|
lhs.CopyTo(path, 0);
|
|
path[lhs.Count] = rhs;
|
|
return new AdaptablePath<T>(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Concatenates 2 paths</summary>
|
|
/// <param name="lhs">First path. Can be null.</param>
|
|
/// <param name="rhs">Second path. Can be null.</param>
|
|
/// <returns>Concatenated path, with rhs as prefix and lhs as suffix. Is null if both lhs and rhs are null.</returns>
|
|
public static AdaptablePath<T> operator +(AdaptablePath<T> lhs, AdaptablePath<T> 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<T>(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts from the path type to another type</summary>
|
|
/// <typeparam name="U">Desired type</typeparam>
|
|
/// <param name="item">Item to convert</param>
|
|
/// <returns>Item converted to given type or null</returns>
|
|
protected override U Convert<U>(T item)
|
|
{
|
|
U u = item.As<U>();
|
|
return u;
|
|
}
|
|
}
|
|
} |