Добавлен Devion,
опубликован
Я уже выкладывал код данной монады в разделе "программирование". Однако Unity 5 имеет весьма специфичное сравнение с null для своих объектов, из-за чего тот код не совсем валиден.
Так скажем это "код с костылем".
Так скажем это "код с костылем".
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace System.Monads
{
/// <summary> Для словарей </summary>
public static class MaybeIDictionary
{
/// <summary> Выполняет действие с каждым элементом словаря, если словарь существует </summary>
public static IDictionary<TKey, TValue> Do<TKey, TValue>(this IDictionary<TKey, TValue> source,
Action<TKey, TValue> action)
{
if (source != null)
{
foreach (var element in source)
{
action(element.Key, element.Value);
}
}
return source;
}
/// <summary> Достает значение по указанному ключу, если словарь существует и имеет такой ключ. В противном случае возвращает значение типа по умолчанию. </summary>
public static TValue With<TKey, TValue>(this IDictionary<TKey, TValue> source, TKey key)
{
if (source != null)
{
TValue result;
if (source.TryGetValue(key, out result))
return result;
}
return default(TValue);
}
/// <summary>
/// Достает значение по указанному ключу, если словарь существует и имеет такой ключ. В противном случае возвращает заданное нами значение по умолчанию </summary>
public static TValue Return<TKey, TValue>(this IDictionary<TKey, TValue> source, TKey key, TValue defaultValue)
{
if (source != null)
{
TValue result;
if (source.TryGetValue(key, out result))
return result;
}
return defaultValue;
}
}
/// <summary> Для перечислений - массивы, списки </summary>
public static class MaybeIEnumerable
{
/// <summary> Выполняет указанное действие с каждым элементом списка, если список существует </summary>
public static IEnumerable Do(this IEnumerable source, Action<object> action)
{
var enumerable = source as object[] ?? source.Cast<object>().ToArray();
if (source != null)
foreach (var element in enumerable)
action(element);
return enumerable;
}
/// <summary> Выполняет указанное действие с каждым элементом списка, если список существует </summary>
public static IEnumerable<TSource> Do<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
var enumerable = source as TSource[] ?? source.ToArray();
if (source != null)
foreach (var element in enumerable)
action(element);
return enumerable;
}
/// <summary> Выполняет указанное действие с каждым элементом списка, если список существует </summary>
public static IEnumerable<TSource> Do<TSource>(this IEnumerable<TSource> source, Action<TSource, int> action)
{
var enumerable = source as TSource[] ?? source.ToArray();
if (source != null)
foreach (var element in enumerable.Select((s, i) => new { Source = s, Index = i }))
action(element.Source, element.Index);
return enumerable;
}
/// <summary> Проталкивает указанное поле, если список существует. Аналог Select() грубо говоря </summary>
public static IEnumerable<TResult> With<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> action)
{
return source != null ? source.Select(action) : null;
}
}
public static class MaybeNullable
{
/// <summary> Выполняет указанное действие, если объект существует. </summary>
public static TSource? Do<TSource>(this TSource? source, Action<TSource?> action)
where TSource : struct
{
if (source.HasValue)
action(source);
return source;
}
/// <summary> Проталкивает указанное значение, если объект существует и значение типа по умолчанию, если не существует </summary>
public static TResult With<TSource, TResult>(this TSource? source, Func<TSource?, TResult> action)
where TSource : struct
{
return source.HasValue ? action(source) : default(TResult);
}
/// <summary> Проталкивает указанное значение, если объект существует и значение указанного нами типа, если не существует </summary>
public static TResult Return<TSource, TResult>(this TSource? source, Func<TSource?, TResult> action, TResult defaultValue)
where TSource : struct
{
return source.HasValue ? action(source) : defaultValue;
}
/// <summary> Проталкивает значение дальше, если выполняется условие, в противном случае возвращает значение типа по умолчанию </summary>
public static TSource? If<TSource>(this TSource? source, Func<TSource?, bool> condition)
where TSource : struct
{
return source.HasValue && condition(source) ? source : default(TSource);
}
/// <summary> Пироталкивает значение дальше, если условие не выполняется, в противном случае возвращает значение по умолчанию </summary>
public static TSource? IfNot<TSource>(this TSource? source, Func<TSource?, bool> condition)
where TSource : struct
{
return source.HasValue && !condition(source) ? source : default(TSource);
}
/// <summary> Если объект не существует, восстанавливает его указанным способом </summary>
public static TInput Recover<TInput>(this TInput? source, Func<TInput> recoverFunc)
where TInput : struct
{
return source.HasValue ? source.Value : recoverFunc();
}
/// <summary> Возвращает true если объект не существует </summary>
public static bool IsNull<TSource>(this TSource? source)
where TSource : struct
{
return source.HasValue == false;
}
/// <summary> Возвращает true если объект существует </summary>
public static bool IsNotNull<TSource>(this TSource? source)
where TSource : struct
{
return source.HasValue;
}
}
public static class MaybeObjects
{
/// <summary> Выполняет действие, если объект существует </summary>
public static TSource Do<TSource>(this TSource source, Action<TSource> action)
where TSource : class
{
if (checkNotNull(source))
action(source);
return source;
}
/// <summary> Выполняет действие, если объект существует </summary>
public static TSource DoNull<TSource>(this TSource source, Action action)
where TSource : class
{
if (checkNull(source))
action();
return source;
}
/// <summary> Проталкивает значение, если объект существует </summary>
public static TResult With<TSource, TResult>(this TSource source, Func<TSource, TResult> action)
where TSource : class
{
return checkNotNull(source) ? action(source) : default(TResult);
}
/// <summary> Проталкивает значение, если объект существует, иначе возвращает наше значение по умолчанию </summary>
public static TResult Return<TSource, TResult>(this TSource source, Func<TSource, TResult> action, TResult defaultValue)
where TSource : class
{
return checkNotNull(source) ? action(source) : defaultValue;
}
/// <summary> Проталкивает значение, если объект существует, иначе возвращает наше значение по умолчанию </summary>
public static bool ReturnSuccess<TSource>(this TSource source)
where TSource : class
{
return checkNotNull(source);
}
/// <summary> Проталкивает значение дальше, если выполняется условие </summary>
public static TSource If<TSource>(this TSource source, Func<TSource, bool> condition)
where TSource : class
{
return checkNotNull(source) && condition(source) ? source : default(TSource);
}
/// <summary> Проталкивает значение дальше, если условие не выполняется</summary>
public static TSource IfNot<TSource>(this TSource source, Func<TSource, bool> condition)
where TSource : class
{
return checkNotNull(source) && !condition(source) ? source : default(TSource);
}
/// <summary> Восстанавливает объект указанным способом если он не существует </summary>
public static TInput Recover<TInput>(this TInput source, Func<TInput> action)
where TInput : class
{
return source ?? action();
}
/// <summary> Восстанавливает объект указанным способом если он не существует, и удаляет, если не существует </summary>
public static TInput Else<TInput>(this TInput source, Func<TInput> action)
where TInput : class
{
return checkNotNull(source) ? null : action();
}
/// <summary> Преобразует объект в указанный тип </summary>
public static TResult OfType<TResult>(this object source)
{
return source is TResult ? (TResult)source : default(TResult);
}
public static TInput Throw<TInput>(this TInput source)
where TInput : class
{
if (checkNull(source))
throw new NullReferenceException(string.Format("Source of type {0} can not be null", typeof(TInput)));
return source;
}
public static TInput Throw<TInput>(this TInput source, string nullExceptionText)
where TInput : class
{
if (checkNull(source))
throw new NullReferenceException(nullExceptionText);
return source;
}
public static TInput Throw<TInput>(this TInput source, params string[] nullExceptionTexts)
where TInput : class
{
if (checkNull(source))
throw new NullReferenceException(nullExceptionTexts != null
? string.Join(Environment.NewLine, nullExceptionTexts)
: string.Format("Source of type {0} can not be null", typeof(TInput)));
return source;
}
/// <summary> Возвращает true если объект не существует </summary>
public static bool IsNull<TSource>(this TSource source)
where TSource : class
{
return checkNull(source);
}
/// <summary> Возвращает true если объект существует </summary>
public static bool IsNotNull<TSource>(this TSource source)
where TSource : class
{
return checkNotNull(source);
}
public static T ChangeIf<T>(this T o, Predicate<T> predicate, Func<T, T> func)
{
if (predicate(o))
return func(o);
return o;
}
//Из за бага UnityEngine.Object с проверкой на null проверять нужно через эти функции
private static bool checkNull(object a)
{
return a == null || a.Equals(null);
}
private static bool checkNotNull(object a)
{
return !checkNull(a);
}
}
}
`
ОЖИДАНИЕ РЕКЛАМЫ...
Комментарии пока отсутcтвуют.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.