C# String Operator Overloading

前端 未结 7 2022
自闭症患者
自闭症患者 2020-12-19 04:02

G\'Day Mates -

What is the right way (excluding the argument of whether it is advisable) to overload the string operators <, >, <= and >= ?

I\'ve trie

7条回答
  •  萌比男神i
    2020-12-19 04:37

    After 10 years you can do it (to some degree) using a wrapper class and implicit conversions.
    But just because you can doesn't mean you should.

    Here it is some code:

        // implements all interfaces that string does through the field content
        public sealed class StringWrapper : IEnumerable, ICloneable, IComparable, IComparable, IConvertible, IEquatable
        {
            private readonly string content;
    
            private StringWrapper(string content)
            {
                this.content = content;
            }
    
            // implicit conversions
            public static implicit operator string(StringWrapper d) => d.content;
            public static implicit operator StringWrapper(string b) => new StringWrapper(b);
    
            public static bool operator <(StringWrapper lhs, StringWrapper rhs)
            {
                return lhs.content.CompareTo(rhs.content) < 0;
            }
    
            public static bool operator >(StringWrapper lhs, StringWrapper rhs)
            {
                return lhs.content.CompareTo(rhs.content) > 0;
            }
    
            // string supports it, why shouldnt we?
            public static StringWrapper operator +(StringWrapper lhs, StringWrapper rhs)
            {
                var sb = new StringBuilder();
                sb.Append(lhs.content);
                sb.Append(rhs.content);
                return sb.ToString();
            }
    
            // at request of @Alexey Khoroshikh
            public static StringWrapper operator *(StringWrapper lhs, int rhs)
            {
                var sb = new StringBuilder();
                for (int i = 0; i < rhs; i++)
                {
                    sb.Append(lhs.content);
                }
                return sb.ToString();
            }
    
            // other nice thing to have
            public static string[] operator /(StringWrapper lhs, char rhs)
            {
                return lhs.content.Split(rhs);
            }
    
            public override bool Equals(object obj)
            {
                return (obj is StringWrapper wrapper && content == wrapper.content)
                    || (obj is string str && content == str);
            }
    
            #region auto-generated code through visual studio
    
            public override int GetHashCode()
            {
                return -1896430574 + EqualityComparer.Default.GetHashCode(content);
            }
    
            public override string ToString()
            {
                return this.content;
            }
    
            public object Clone()
            {
                return content.Clone();
            }
    
            public int CompareTo(string other)
            {
                return content.CompareTo(other);
            }
    
            public bool Equals(string other)
            {
                return content.Equals(other);
            }
    
            public IEnumerator GetEnumerator()
            {
                return ((IEnumerable)content).GetEnumerator();
            }
    
            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return ((System.Collections.IEnumerable)content).GetEnumerator();
            }
    
            public int CompareTo(object obj)
            {
                return content.CompareTo(obj);
            }
    
            public TypeCode GetTypeCode()
            {
                return content.GetTypeCode();
            }
    
            public bool ToBoolean(IFormatProvider provider)
            {
                return ((IConvertible)content).ToBoolean(provider);
            }
    
            public byte ToByte(IFormatProvider provider)
            {
                return ((IConvertible)content).ToByte(provider);
            }
    
            public char ToChar(IFormatProvider provider)
            {
                return ((IConvertible)content).ToChar(provider);
            }
    
            public DateTime ToDateTime(IFormatProvider provider)
            {
                return ((IConvertible)content).ToDateTime(provider);
            }
    
            public decimal ToDecimal(IFormatProvider provider)
            {
                return ((IConvertible)content).ToDecimal(provider);
            }
    
            public double ToDouble(IFormatProvider provider)
            {
                return ((IConvertible)content).ToDouble(provider);
            }
    
            public short ToInt16(IFormatProvider provider)
            {
                return ((IConvertible)content).ToInt16(provider);
            }
    
            public int ToInt32(IFormatProvider provider)
            {
                return ((IConvertible)content).ToInt32(provider);
            }
    
            public long ToInt64(IFormatProvider provider)
            {
                return ((IConvertible)content).ToInt64(provider);
            }
    
            public sbyte ToSByte(IFormatProvider provider)
            {
                return ((IConvertible)content).ToSByte(provider);
            }
    
            public float ToSingle(IFormatProvider provider)
            {
                return ((IConvertible)content).ToSingle(provider);
            }
    
            public string ToString(IFormatProvider provider)
            {
                return content.ToString(provider);
            }
    
            public object ToType(Type conversionType, IFormatProvider provider)
            {
                return ((IConvertible)content).ToType(conversionType, provider);
            }
    
            public ushort ToUInt16(IFormatProvider provider)
            {
                return ((IConvertible)content).ToUInt16(provider);
            }
    
            public uint ToUInt32(IFormatProvider provider)
            {
                return ((IConvertible)content).ToUInt32(provider);
            }
    
            public ulong ToUInt64(IFormatProvider provider)
            {
                return ((IConvertible)content).ToUInt64(provider);
            }
    
            #endregion auto-generated code through visual studio
        }
    
    

提交回复
热议问题