C# 7.0 下Range使用

C#7.0下没有Range类型,只有在C# 8.0之后语法(.netCore,.netStandard支持8.0)之后才有,但是.netframework目前最高支持到7.0.如果想在.netframework下使用,就需要模拟Range

原文链接:https://www.cnblogs.com/Multi-Heartbeat/p/13227419.html

不过原文有点小bug,完善后代码如下

// define Range object
    public struct Range
    {
        private int startIndex;
        private int endIndex;
        private bool isNotNull;

        public Range(int startIndex, int endIndex)
        {
            
            this.startIndex = startIndex;
            this.endIndex = endIndex;
            this.isNotNull = true;
        }

        public bool IsNull
        {
            get
            {
                return !this.isNotNull;
            }
        }

        internal void CheckNull()
        {
            if (this.IsNull)
            {
                throw new Exception("this object is null");
            }
        }

        public int StartIndex
        {
            get
            {
                CheckNull();
                return this.startIndex;
            }
        }

        public int EndIndex
        {
            get
            {
                CheckNull();
                return this.endIndex;
            }
        }

        public int Count
        {
            get
            {
                if (IsNull)
                {
                    return 0;
                }
                return this.endIndex - this.startIndex;
            }
        }

        public static implicit operator Range(string input)
        {
            if (string.IsNullOrEmpty(input))
            {
                return default(Range);
            }
            Regex re = new Regex(@"^(\^?)\d+\.\.(\^?)\d+$");
            Regex re3 = new Regex(@"^\.\.(\^?)\d+$");
            Regex re2 = new Regex(@"^(\^?)\d+\.\.$");
            Match match = null;
            int matchFlag = 0;
            if (re.IsMatch(input))
            {
                matchFlag = 1;
                match = re.Match(input);
            }
            else if (re2.IsMatch(input))
            {
                matchFlag = 2;
                match = re2.Match(input);
            }
            else if (re3.IsMatch(input))
            {
                matchFlag = 3;
                match = re3.Match(input);
            }
            // match fails
            if (0 == matchFlag)
            {
                return default(Range);
            }
            //string[] strs = match.Value.Split(new char[]{ '.','.'}, StringSplitOptions.RemoveEmptyEntries);
            string[] strs = match.Value.Split(new string[] { ".." }, StringSplitOptions.RemoveEmptyEntries);
            //两种写法都可以
            int startIndex, endIndex;
            int.TryParse(strs[0].Replace("^", "-"), out startIndex);
            int.TryParse(strs[1].Replace("^", "-"), out endIndex);
            if (2 == matchFlag)
            {
                endIndex = int.MaxValue;
            }
            else if (3 == matchFlag)
            {
                startIndex = 0;
            }
            return new Range(startIndex, endIndex);
        }
    }
    //添加对string的扩展方法
    public static class ObjectExtension
    {
        public static string Span(this string val, string input, bool isValidate = true)
        {
            if (string.IsNullOrEmpty(val) || string.IsNullOrEmpty(input))
            {
                return val;
            }
            Range range = input;
            return GetString(val, range, isValidate);
        }

        public static string Span(this string val, Range range, bool isValidate = true)
        {
            if (string.IsNullOrEmpty(val) || range.IsNull)
            {
                return val;
            }
            return GetString(val, range,isValidate);
        }

        private static string GetString(string val, Range range,bool isValidate)
        {
            int len = val.Length;
            int startIndex = range.StartIndex < 0 ? len + range.StartIndex : range.StartIndex;
            int endIndex = range.EndIndex < 0 ? len + range.EndIndex : range.EndIndex;
            if (range.EndIndex == int.MaxValue)
            {
                endIndex = len;
            }
            if (isValidate && startIndex > endIndex)
            {
                throw new IndexOutOfRangeException("startIndex must be equal or less than endIndex.");
            }
            int count = endIndex - startIndex;
            return val.Substring(startIndex, count);
        }
    }

 

测试例子

class Program
{
    static void Main(string[] args)
    {
        string str = "adfgafd";
        Range range = "1..^1";
        string str1 = str.Span(range);
        string str2 = str.Span("1..^1");
    }
}

结果:dfgaf dfgaf

总体上代码有点复杂,性能也一般,不过不失为一种实现高级语言语法糖的思路

 

posted @ 2020-08-28 15:27  zhaogaojian  阅读(1018)  评论(0编辑  收藏  举报