using Apewer;
using Apewer.Internals;
using Apewer.Source;
using Apewer.Surface;
using Apewer.Web;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
#if NETFX || NETCORE
using System.Windows.Forms;
#endif
/// 扩展方法。
public static class Extensions
{
#region Class Utility
/// 克隆对象,创建新对象。可指定包含对象的属性和字段。
public static T Clone(this T @this, T failed = default(T), bool properties = true, bool fields = false) where T : new()
{
return ClassUtility.Clone(@this, failed, properties, fields);
}
/// 解析源对象。
public static Dictionary GetOrigin(this TextSet @this)
{
return ClassUtility.GetOrigin(@this);
}
/// 解析源对象。
public static Dictionary GetOrigin(this ObjectSet @this)
{
return ClassUtility.GetOrigin(@this);
}
/// 解析源对象。
public static Dictionary GetOrigin(this ObjectSet @this)
{
return ClassUtility.GetOrigin(@this);
}
/// 调用 Get 方法。
public static object Get(this PropertyInfo @this, object instance)
{
return ClassUtility.InvokeGet(instance, @this);
}
/// 调用 Set 方法。
public static void Set(this PropertyInfo @this, object instance, object value)
{
ClassUtility.InvokeSet(instance, @this, value);
}
/// 调用 Get 方法。
public static T Get(this PropertyInfo @this, object instance)
{
return ClassUtility.InvokeGet(instance, @this);
}
/// 调用 Set 方法。
public static void Set(this PropertyInfo @this, object instance, T value)
{
ClassUtility.InvokeSet(instance, @this, value);
}
/// 调用方法。
///
///
///
///
///
///
///
public static object Invoke(this MethodInfo @this, object instace, params object[] parameters)
{
return ClassUtility.InvokeMethod(instace, @this, parameters);
}
/// 遍历公开属性。
public static void ForEachProperties(this Type @this, Action action)
{
ClassUtility.ForEachPublicProperties(@this, action);
}
/// 判断静态属性。
public static bool IsStatic(this PropertyInfo @this)
{
return ClassUtility.IsStatic(@this);
}
/// 判断类型。
public static bool TypeEquals(this object @this)
{
return ClassUtility.TypeEquals(@this, typeof(T));
}
#endregion
#region Number
private static bool Equals(this T @this, T value) where T : IComparable
{
return @this.CompareTo(value) == 0;
}
///
public static bool IsZero(this decimal @this)
{
return @this.Equals(0M);
}
///
public static bool IsZero(this double @this)
{
return @this.Equals(0D);
}
///
public static bool IsZero(this float @this)
{
return @this.Equals(0F);
}
///
public static bool NotZero(this decimal @this)
{
return !@this.Equals(0M);
}
///
public static bool NotZero(this double @this)
{
return !@this.Equals(0D);
}
///
public static bool NotZero(this float @this)
{
return !@this.Equals(0F);
}
/// 约束值范围,若源值不在范围中,则修改为接近的值。
public static T RestrictValue(this T @this, T min, T max) where T : IComparable
{
return NumberUtility.RestrictValue(@this, min, max);
}
///
[CLSCompliant(false)]
public static Byte ToByte(this IConvertible @this)
{
return @this.ToByte(null);
}
///
[CLSCompliant(false)]
public static Int32 ToInt32(this IConvertible @this)
{
return @this.ToInt32(null);
}
///
[CLSCompliant(false)]
public static Int64 ToInt64(this IConvertible @this)
{
return @this.ToInt64(null);
}
///
[CLSCompliant(false)]
public static Double ToDouble(this IConvertible @this)
{
return @this.ToDouble(null);
}
///
[CLSCompliant(false)]
public static Decimal ToDecimal(this IConvertible @this)
{
return @this.ToDecimal(null);
}
#endregion
#region String、StringBuilder
///
public static Int32 ToInt32(this string @this) { return TextUtility.GetInt32(@this); }
///
public static Int64 ToInt64(this string @this) { return TextUtility.GetInt64(@this); }
///
public static Decimal ToDecimal(this string @this) { return TextUtility.GetDecimal(@this); }
///
public static Double ToDouble(this string @this) { return TextUtility.GetDouble(@this); }
/// 将文本转换为字节数组,默认为 UTF-8。
public static byte[] ToBinary(this string @this, Encoding encoding = null) { return TextUtility.ToBinary(@this, encoding); }
/// 验证字符串为 NULL、为空或仅含空白。
public static bool IsEmpty(this string @this) { return TextUtility.IsEmpty(@this); }
/// 验证字符串为 NULL、为空或仅含空白。
public static bool NotEmpty(this string @this) { return TextUtility.NotEmpty(@this); }
/// 验证字符串为 NULL、为空或无实际内容。
///
/// 所有情况,包含全角。
public static bool IsBlank(this string @this, bool allCases = false) { return TextUtility.IsBlank(@this, allCases); }
/// 验证字符串含有实际内容。
///
/// 所有情况,包含全角。
public static bool NotBlank(this string @this, bool allCases = false) { return TextUtility.NotBlank(@this, allCases); }
/// 将文本转换为字节数组,默认为 UTF-8。
public static byte[] GetBytes(this string @this, Encoding encoding = null) { return TextUtility.ToBinary(@this, encoding); }
/// 用指定的分隔符拆分文本。
public static string[] Split(this string @this, string separator) { return TextUtility.Split(@this, separator); }
/// 使用多个分隔符切分字符串,得到多个子字符串。
public static string[] Split(this string @this, params char[] separators) { return TextUtility.Split(@this, separators); }
/// 返回此字符串的安全键副本。
public static string SafeKey(this string @this) { return TextUtility.RestrictGuid(@this); }
/// 移除字符串前后的空白。
public static string SafeTrim(this string @this) { return TextUtility.Trim(@this); }
/// 移除字符串前后的空白。
///
/// 所有情况,全角空格将被去除。
public static string SafeTrim(this string @this, bool allCases) { return TextUtility.Trim(@this, allCases); }
/// 返回此字符串转换为小写形式的副本。
public static string SafeLower(this string @this) { return TextUtility.ToLower(@this); }
/// 返回此字符串转换为大写形式的副本。
public static string SafeUpper(this string @this) { return TextUtility.ToUpper(@this); }
/// 约束字符串用于 Key。
public static string RestrictKey(this string @this) { return TextUtility.RestrictGuid(TextUtility.ToLower(@this)); }
/// 约束字符串长度范围,超出的部分将被截取去除。
public static string RestrictLength(this string @this, int length) { return TextModifier.RestrictLength(@this, length); }
/// 约束字符串长度为 32,超出的部分将被截取去除。
public static string Restrict32(this string @this) { return TextModifier.RestrictLength(@this, 32); }
/// 约束字符串长度为 255,超出的部分将被截取去除。
public static string Restrict255(this string @this) { return TextModifier.RestrictLength(@this, 255); }
/// 约束字符串长度为 2000,超出的部分将被截取去除。
public static string Restrict2000(this string @this) { return TextModifier.RestrictLength(@this, 2000); }
/// 追加字符串。
public static string Append(this string @this, params object[] text) { return TextUtility.Merge(@this, TextUtility.Merge(text)); }
/// 追加文本。
public static void Append(this StringBuilder @this, params object[] text) { TextUtility.Append(@this, text); }
/// 防注入处理,去除会引发代码注入的字符。可限定字符串长度。
public static string AntiInject(this string @this, int length = -1, string blacklist = null) { return TextUtility.AntiInject(@this, length, blacklist); }
/// 将 Base64 字符串转换为字节数组。
public static byte[] AntiBase64(this string @this) { return BinaryUtility.FromBase64(@this); }
/// 对 URL 编码。
public static string EncodeUrl(this string @this) { return UrlEncoding.Encode(@this); }
/// 对 URL 解码。
public static string DecodeUrl(this string @this) { return UrlEncoding.Decode(@this); }
#endregion
#region Byte[]
/// 将字节数组格式化为大写十六进制字符串。例:D41D8CD98F00B204E9800998ECF8427E
public static string ToX2(this byte[] @this) { return BinaryUtility.ToX2(@this); }
/// 克隆字节数组。当源为 NULL 时,将获取零元素字节数组。
public static byte[] Clone(this byte[] @this) { return BinaryUtility.Clone(@this); }
/// 确定此字节数组实例的开头是否与指定的字节数组匹配。
public static bool StartsWith(this byte[] @this, params byte[] head) { return BinaryUtility.StartsWith(@this, head); }
/// 确定此字节数组实例的结尾是否与指定的字节数组匹配。
public static bool EndsWith(this byte[] @this, params byte[] head) { return BinaryUtility.EndsWith(@this, head); }
/// 将字节数组转换为 Base64 字符串。
public static string ToBase64(this byte[] @this) { return BinaryUtility.ToBase64(@this); }
/// 获取 MD5 值。
public static byte[] GetMD5(params byte[] @this) { return BinaryUtility.MD5(@this); }
/// 获取 SHA1 值。
public static byte[] GetSHA1(params byte[] @this) { return BinaryUtility.SHA1(@this); }
#if !NET20
/// 获取 SHA256 值。
public static byte[] GetSHA256(params byte[] @this) { return BinaryUtility.SHA256(@this); }
#endif
/// 将字节数组转换为文本,默认为 UTF-8。
public static string GetString(this byte[] @this, Encoding encoding = null) { return TextUtility.FromBinary(@this, encoding); }
/// 将字节数组转换为文本,默认为 UTF-8。
public static string ToText(this byte[] @this, Encoding encoding = null) { return TextUtility.FromBinary(@this, encoding); }
/// 为文本数据添加 BOM 字节,若已存在则忽略。
public static byte[] AddTextBom(this byte[] @this) { return BinaryUtility.AddTextBom(@this); }
/// 去除文本数据的 BOM 字节,若不存在则忽略。
public static byte[] WipeTextBom(this byte[] @this) { return BinaryUtility.WipeTextBom(@this); }
/// 为字节数组增加字节。
public static byte[] Append(this byte[] @this, params byte[] bytes) { return BinaryUtility.Append(@this, bytes); }
/// 检查字节数组是 UTF-8 文本,默认最多检测 1MB 数据。
/// 要检查的字节数组。
/// 检查的最大字节长度,指定为 0 将不限制检查长度。
public static bool IsUTF8(this byte[] @this, int checkLength = 1048576) { return BinaryUtility.IsUTF8(@this, checkLength, null); }
/// 检查字节数组包含 UTF-8 BOM 头。
public static bool ContainsBOM(this byte[] @this) { return BinaryUtility.ContainsBOM(@this); }
#endregion
#region DateTime
/// 获取毫秒时间戳。
public static long GetStamp(this DateTime @this)
{
return DateTimeUtility.GetStamp(@this);
}
/// 获取毫秒时间戳。
public static long ToStamp(this DateTime @this)
{
return DateTimeUtility.ToStamp(@this);
}
/// 转换为易于阅读的文本。
public static string ToLucid(this DateTime @this, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true)
{
return DateTimeUtility.ToLucid(@this, date, time, seconds, milliseconds);
}
/// 转换为紧凑的文本。
public static string ToCompact(this DateTime @this, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true)
{
return DateTimeUtility.ToCompact(@this, date, time, seconds, milliseconds);
}
/// 当前 DateTime 为闰年。
public static bool IsLeapYear(this DateTime @this)
{
return DateTimeUtility.IsLeapYear(DateTimeUtility.GetDateTime(@this).Year);
}
#endregion
#region Json
/// 生成 JSON 对象,失败时返回 NULL。
/// 将要解析的对象。
/// 在 Json 中将属性名称转换为小写。
/// 解析深度。
/// 强制解析所有属性,忽略 Serializable 特性。
public static Json ToJson(this IDictionary @this, bool lowerCase = false, int depth = -1, bool force = false)
{
return Json.Parse(@this, lowerCase, depth, force);
}
/// 解析实现 IList 的对象为 Json 对象,失败时返回 Null。
/// 将要解析的对象。
/// 在 Json 中将属性名称转换为小写。
/// 解析深度。
/// 强制解析所有属性,忽略 Serializable 特性。
public static Json ToJson(this IList @this, bool lowerCase = false, int depth = -1, bool force = false)
{
return Json.Parse(@this, lowerCase, depth, force);
}
///
/// 解析对象为 Json 对象,包含所有公共属性,失败时返回 Null。
/// String 对象将解析文本;Json 对象将返回实例;String 对象将解析文本;实现 IDictionary 或 IList 的对象将解析内容。
///
/// 将要解析的对象。
/// 在 Json 中将属性名称转换为小写。
/// 解析深度。
/// 强制解析所有属性,忽略 Serializable 特性。
///
public static Json ToJson(object @this, bool lowerCase = false, int depth = -1, bool force = false)
{
return Json.Parse(@this, lowerCase, depth, force);
}
/// 填充类型实例,失败时返回 NULL 值。
/// 将要解析的对象。
/// 忽略属性名称大小写。
/// 忽略的属性名称字符。
/// 强制填充,忽略 的 Serializable 特性。
public static T FillObject(this Json @this, bool ignoreCase = true, string ignoreCharacters = null, bool force = false) where T : class, new()
{
return Json.FillObject(@this, ignoreCase, ignoreCharacters, force);
}
/// 填充类型实例,失败时返回 NULL 值。
/// 将要解析的对象。
/// 忽略属性名称大小写。
/// 忽略的属性名称字符。
/// 强制填充,忽略 的 Serializable 特性。
public static List FillArray(this Json @this, bool ignoreCase = true, string ignoreCharacters = null, bool force = false) where T : class, new()
{
return Json.FillArray(@this, ignoreCase, ignoreCharacters, force);
}
/// 设置属性名称为小写。
public static Json ToLower(this Json @this)
{
return Json.ToLower(@this);
}
#endregion
#region Stream
/// 重置流的位置到开始位置。
public static bool ResetPosition(this Stream @this)
{
return StreamHelper.ResetPosition(@this);
}
/// 读取源流中的数据,并将数据写入目标流,获取写入的字节数。
public static long Read(this Stream @this, Stream destination, Action progress = null)
{
return BinaryUtility.Read(@this, destination, progress);
}
/// 读取源流中的数据,获取写入的字节。
public static byte[] Read(this Stream @this, bool dispose = false)
{
return BinaryUtility.Read(@this, dispose);
}
/// 向流写入数据。
/// 源流。
/// 要写入的数据。
public static long Write(this Stream @this, params byte[] bytes)
{
return BinaryUtility.Write(@this, bytes);
}
/// 读取源流中的数据,并将数据写入当前流,获取写入的字节数。
/// 目标流。
/// 源流。
public static long Write(this Stream @this, Stream source)
{
return StreamHelper.Read(source, @this);
}
/// 获取 MD5 值。
public static byte[] MD5(this Stream @this)
{
return BinaryUtility.MD5(@this);
}
/// 获取 SHA1 值。
public static byte[] SHA1(this Stream @this)
{
return BinaryUtility.SHA1(@this);
}
#if !NET20
/// 获取 SHA256 值。
public static byte[] SHA256(this Stream @this)
{
return BinaryUtility.SHA256(@this);
}
#endif
#endregion
#region Type
/// 判断指定类型具有特性。
public static bool ContainsAttribute(this Type @this, bool inherit = false) where T : Attribute
{
return ClassUtility.ContainsAttribute(@this, inherit);
}
#endregion
#region IEnumerable、Array、List、Dictionary
///
///
public static void Add(this IList @this, params T[] items)
{
if (@this == null) throw new ArgumentNullException();
foreach (var item in items) @this.Add(item);
}
///
///
public static void Add(this IList @this, IEnumerable items)
{
if (@this == null) throw new ArgumentNullException();
foreach (var item in items) @this.Add(item);
}
///
public static bool IsEmpty(this IEnumerable @this) { return ClassUtility.IsEmpty(@this); }
///
public static bool NotEmpty(this IEnumerable @this) { return ClassUtility.NotEmpty(@this); }
///
public static bool Contains(this IEnumerable @this, T cell) { return ClassUtility.Contains(@this, cell); }
///
public static List Sub(this IEnumerable @this, long start = 0, long count = -1, Func stuffer = null) { return ClassUtility.Sub(@this, start, count, stuffer); }
/// 安全转换为 List< > 对象。可指定排除 NULL 值元素。
///
public static List SafeList(this IEnumerable @this, bool excludeNull = false) { return ClassUtility.ToList(@this, excludeNull); }
/// 升序排序。
public static List SortAscend(this List @this) where T : IComparable
{
return SortUtility.AscendT(@this);
}
/// 降序排序。
public static List SortDescend(this List @this) where T : IComparable
{
return SortUtility.DescendT(@this);
}
/// 对 Key 排序。
public static Dictionary SortKey(this Dictionary @this, bool ascend = true)
{
return SortHelper.DictionaryStringString(@this, true, ascend);
}
/// 对 Value 排序。
public static Dictionary SortValue(this Dictionary @this, bool ascend = true)
{
return SortHelper.DictionaryStringString(@this, false, ascend);
}
/// 对 Key 排序。
public static Dictionary SortKey(this Dictionary @this, bool ascend = true)
{
return SortHelper.DictionaryStringDouble(@this, true, ascend);
}
/// 对 Value 排序。
public static Dictionary SortValue(this Dictionary @this, bool ascend = true)
{
return SortHelper.DictionaryStringDouble(@this, false, ascend);
}
/// 获取列表中的第一个 Item 对象。可指定失败时的默认返回值。
public static T SafeFirst(this IList @this, T failed = default(T))
{
if (@this == null) return failed;
if (@this.Count < 1) return failed;
return @this[0];
}
/// 添加元素。
///
///
///
///
///
public static bool Add(this IList> @this, TKey key, TValue value)
{
if (@this == null) return false;
@this.Add(new KeyValuePair(key, value));
return true;
}
#endregion
#region Source
/// 为记录的 Key 属性设置新值。
public static void SetNewKey(this Record @this)
{
if (@this != null) @this.Key = Record.GenerateKey();
}
/// 修补基本属性。
public static void FixProperties(this Record @this)
{
Record.FixProperties(@this);
}
///
public static DateTime DateTime(this IQuery @this, int row, string column)
{
if (@this == null) return DateTimeUtility.Origin;
var value = @this.Value(row, column);
if (value == null) return DateTimeUtility.Origin;
if (value is DateTime) return (DateTime)value;
DateTime result;
var parsed = System.DateTime.TryParse(value.ToString(), out result);
return parsed ? result : DateTimeUtility.Origin;
}
///
public static Int32 Int32(this IQuery @this, int row, string column)
{
if (@this == null) return 0;
return ToInt32(@this.Text(row, column));
}
///
public static Int64 Int64(this IQuery @this, int row, string column)
{
if (@this == null) return 0L;
return ToInt64(@this.Text(row, column));
}
///
public static Decimal Decimal(this IQuery @this, int row, string column)
{
if (@this == null) return 0M;
return ToDecimal(@this.Text(row, column));
}
///
public static Double Double(this IQuery @this, int row, string column)
{
if (@this == null) return 0d;
return ToDouble(@this.Text(row, column));
}
#endregion
#region Web API
#if NETFX
/// 获取查询字符串。
public static string QueryString(this ApiRequest @this, string name, bool decode = false)
{
return PageUtility.QueryString(name, decode);
}
/// 获取表单。
public static string Form(this ApiRequest @this, string name)
{
return PageUtility.RequestForm(name);
}
/// 获取 URL 查询段,不存在的段为 NULL 值。可要求解码。
public static string GetSegmental(this Uri @this, int index = 3, bool decode = false)
{
return WebUtility.GetSegmental(@this, index, decode);
}
/// 获取 URL 查询段,不存在的段为 NULL 值。可要求解码。
public static string GetSegmentalUrl(this ApiRequest @this, int index = 3, bool decode = false)
{
return WebUtility.GetSegmentalUrl(@this, index, decode);
}
/// 获取参数,指定可能的参数名,从 URL 中获取参数时将解码。
public static string GetParameter(this ApiRequest @this, params string[] names)
{
return WebUtility.GetParameter(@this, names);
}
#endif
#if NETFX || NETCORE
/// 设置 status 为 error,并设置 message 的内容。
public static void Error(this ApiResponse @this, string message = "未知错误。")
{
ApiInternals.RespondError(@this, message);
}
/// 设置 status 为 error,并设置 message 的内容。
public static void Error(this ApiResponse @this, Exception exception)
{
ApiInternals.RespondError(@this, exception);
}
/// 输出 UTF-8 文本。
public static void Text(this ApiResponse @this, string content, string type = "text/plain")
{
ApiInternals.RespondText(@this, content, type);
}
/// 输出字节数组。
public static void Binary(this ApiResponse @this, byte[] content, string type = "application/octet-stream")
{
ApiInternals.RespondBinary(@this, content, type);
}
/// 输出二进制。
public static void Binary(this ApiResponse @this, Stream content, string type = "application/octet-stream")
{
ApiInternals.RespondBinary(@this, content, type);
}
/// 输出文件。
public static void File(this ApiResponse @this, Stream stream, string name, string type = "application/octet-stream")
{
ApiInternals.RespondFile(@this, stream, name, type);
}
/// 重定向。
public static void Redirect(this ApiResponse @this, string url)
{
ApiInternals.RespondRedirect(@this, url);
}
///
///
///
///
public static T Use(this ApiController @this) where T : ApiController, new()
{
var current = @this;
var target = new T();
if (current != null)
{
target.Request = current.Request;
target.Response = current.Response;
target.AfterInitialized?.Invoke();
}
return target;
}
///
///
///
///
///
///
public static void Respond(this ApiResponse @this, IList list, bool lower = true, int depth = -1, bool force = false)
{
if (@this == null) return;
if (list == null)
{
@this.Error("获取失败。");
return;
}
@this.Data.SetProperty("count", list.Count);
@this.Data.SetProperty("list", Json.Parse(list, lower, depth, force));
}
///
///
///
///
public static void Respond(this ApiResponse @this, Record record, bool lower = true)
{
if (@this == null) return;
if (record == null)
{
@this.Error("获取失败。");
return;
}
@this.Data.Reset(Json.Parse(record, lower));
}
#endif
#endregion
#region Surface
#if NETFX || NETCORE
///
public static void Invoke(this Control @this, Action action, bool async = false)
{
FormsUtility.Invoke(@this, action, async);
}
#endif
#endregion
}