解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
3.75 KiB
X
#if NETFRAMEWORK || NETSTANDARD2_0
using System.Runtime.CompilerServices;

namespace System;

/// <summary>
/// 表示一个索引,可从序列开头或结尾计算。等同于 .NET Core 的 System.Index。
/// </summary>
public readonly struct Index : IEquatable<Index>
{
    /// <summary>内部存储的索引值。非负表示从开头,负值按位取反后表示从末尾。</summary>
    private readonly Int32 _value;

    /// <summary>表示序列起始位置(0)。</summary>
    public static Index Start => new(0);

    /// <summary>表示序列末尾位置(^0)。</summary>
    public static Index End => new(-1);

    /// <summary>获取绝对值。若 <see cref="IsFromEnd"/> 为 true,则返回从末尾的偏移量。</summary>
    public Int32 Value => _value < 0 ? ~_value : _value;

    /// <summary>指示该索引是否从序列末尾计算。</summary>
    public Boolean IsFromEnd => _value < 0;

    /// <summary>
    /// 使用给定值与是否从末尾的标志创建索引。
    /// </summary>
    /// <param name="value">索引值,必须是非负数。</param>
    /// <param name="fromEnd">是否从末尾计算。</param>
    /// <exception cref="ArgumentOutOfRangeException">当 value 小于 0 时抛出。</exception>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public Index(Int32 value, Boolean fromEnd = false)
    {
        if (value < 0)
        {
            throw new ArgumentOutOfRangeException("value", "value must be non-negative");
        }
        _value = fromEnd ? ~value : value;
    }

    private Index(Int32 value) => _value = value;

    /// <summary>从序列头部创建索引。</summary>
    /// <param name="value">非负索引值。</param>
    /// <returns>从头部计算的索引。</returns>
    /// <exception cref="ArgumentOutOfRangeException">当 value 小于 0 时抛出。</exception>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static Index FromStart(Int32 value)
    {
        if (value < 0)
        {
            throw new ArgumentOutOfRangeException("value", "value must be non-negative");
        }
        return new Index(value);
    }

    /// <summary>从序列尾部创建索引。</summary>
    /// <param name="value">非负索引值。</param>
    /// <returns>从尾部计算的索引。</returns>
    /// <exception cref="ArgumentOutOfRangeException">当 value 小于 0 时抛出。</exception>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static Index FromEnd(Int32 value)
    {
        if (value < 0)
        {
            throw new ArgumentOutOfRangeException("value", "value must be non-negative");
        }
        return new Index(~value);
    }

    /// <summary>
    /// 根据给定序列长度获取该索引对应的偏移量。
    /// </summary>
    /// <param name="length">序列长度。</param>
    /// <returns>偏移量。</returns>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public Int32 GetOffset(Int32 length)
    {
        var offset = _value;
        if (IsFromEnd)
        {
            offset += length + 1;
        }
        return offset;
    }

    /// <inheritdoc />
    public override Boolean Equals(Object value) => value is Index index && _value == index._value;

    /// <inheritdoc />
    public Boolean Equals(Index other) => _value == other._value;

    /// <inheritdoc />
    public override Int32 GetHashCode() => _value;

    /// <summary>从 <see cref="Int32"/> 隐式转换为从起始位置计算的 <see cref="Index"/>。</summary>
    public static implicit operator Index(Int32 value) => FromStart(value);

    /// <inheritdoc />
    public override String ToString()
    {
        if (IsFromEnd)
        {
            return "^" + (UInt32)Value;
        }
        return ((UInt32)Value).ToString();
    }
}
#endif