Files
2025-07-14 12:03:59 +02:00

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;
}
}
}