C# 对象通过ToString()转换成字符串的同时指定具体的格式和语言文化

常规的调用ToString()方法,存在两个问题.

(1)、调用者无法控制字符串的格式

(2)、调用者不能方便的选择一种特定的语言文化来格式化字符串.

在开发一些国际化的应用时,应用程序需要调用与当前线程不同的语言文化来格式化字符串.

so,为了对字符串进行更多的控制,你重写的的ToString()方法应该允许指定具体的格式和语言文化信息.

为了能使调用者在调用对象实例的ToString()方法的时候,选择格式和语言文化,该对象应该实现System.IFormattable接口,接口代码如下:

    //
    // 摘要:
    //     提供一种功能,用以将对象的值格式化为字符串表示形式。
    [ComVisible(true)]
    public interface IFormattable
    {
        //
        // 摘要:
        //     使用指定格式对当前实例的值设置格式。
        //
        // 参数:
        //   format:
        //     要使用的格式。 - 或 - null 引用(在 Visual Basic 中为 Nothing),用于使用为 System.IFormattable 实现的类型定义的默认格式。
        //
        //   formatProvider:
        //     要用于对值设置格式的提供程序。 - 或 - null 引用(在 Visual Basic 中为 Nothing),用于从操作系统的当前区域设置获取数字格式信息。
        //
        // 返回结果:
        //     采用指定格式的当前实例的值。
        string ToString(string format, IFormatProvider formatProvider);
}

FCL(Framework Common Language)中的所有基类型(Byte,SByte,Int16/UInt16,Int32/Uint32,Int64/Uint64,Single,Double,Decimal和Datetime)都实现了这个接口,这些基类型调用ToString方法之后,返回的都是字面值的字符串形式,此外FCL中还有一些类型实现了这个接口.

1、Guid,Guid的ToString代码如下所示:

public unsafe string ToString(string format, IFormatProvider provider)
{
    string str;
    if ((format == null) || (format.Length == 0))
    {
        format = "D";
    }
    int offset = 0;
    bool flag = true;
    bool flag2 = false;
    if (format.Length != 1)
    {
        throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
    }
    char ch = format[0];
    switch (ch)
    {
        case 'D':
        case 'd':
            str = string.FastAllocateString(0x24);
            break;

        case 'N':
        case 'n':
            str = string.FastAllocateString(0x20);
            flag = false;
            break;

        case 'B':
        case 'b':
            str = string.FastAllocateString(0x26);
            fixed (char* str2 = ((char*) str))
            {
                char* chPtr = str2;
                if (chPtr != null)
                {
                    chPtr += RuntimeHelpers.OffsetToStringData;
                }
                chPtr[offset++] = '{';
                chPtr[0x25] = '}';
            }
            break;

        case 'P':
        case 'p':
            str = string.FastAllocateString(0x26);
            fixed (char* str3 = ((char*) str))
            {
                char* chPtr2 = str3;
                if (chPtr2 != null)
                {
                    chPtr2 += RuntimeHelpers.OffsetToStringData;
                }
                chPtr2[offset++] = '(';
                chPtr2[0x25] = ')';
            }
            break;

        default:
            if ((ch != 'X') && (ch != 'x'))
            {
                throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
            }
            str = string.FastAllocateString(0x44);
            fixed (char* str4 = ((char*) str))
            {
                char* chPtr3 = str4;
                if (chPtr3 != null)
                {
                    chPtr3 += RuntimeHelpers.OffsetToStringData;
                }
                chPtr3[offset++] = '{';
                chPtr3[0x43] = '}';
            }
            flag = false;
            flag2 = true;
            break;
    }
    fixed (char* str5 = ((char*) str))
    {
        char* guidChars = str5;
        if (guidChars != null)
        {
            guidChars += RuntimeHelpers.OffsetToStringData;
        }
        if (flag2)
        {
            guidChars[offset++] = '0';
            guidChars[offset++] = 'x';
            offset = HexsToChars(guidChars, offset, this._a >> 0x18, this._a >> 0x10);
            offset = HexsToChars(guidChars, offset, this._a >> 8, this._a);
            guidChars[offset++] = ',';
            guidChars[offset++] = '0';
            guidChars[offset++] = 'x';
            offset = HexsToChars(guidChars, offset, this._b >> 8, this._b);
            guidChars[offset++] = ',';
            guidChars[offset++] = '0';
            guidChars[offset++] = 'x';
            offset = HexsToChars(guidChars, offset, this._c >> 8, this._c);
            guidChars[offset++] = ',';
            guidChars[offset++] = '{';
            offset = HexsToChars(guidChars, offset, this._d, this._e, true);
            guidChars[offset++] = ',';
            offset = HexsToChars(guidChars, offset, this._f, this._g, true);
            guidChars[offset++] = ',';
            offset = HexsToChars(guidChars, offset, this._h, this._i, true);
            guidChars[offset++] = ',';
            offset = HexsToChars(guidChars, offset, this._j, this._k, true);
            guidChars[offset++] = '}';
        }
        else
        {
            offset = HexsToChars(guidChars, offset, this._a >> 0x18, this._a >> 0x10);
            offset = HexsToChars(guidChars, offset, this._a >> 8, this._a);
            if (flag)
            {
                guidChars[offset++] = '-';
            }
            offset = HexsToChars(guidChars, offset, this._b >> 8, this._b);
            if (flag)
            {
                guidChars[offset++] = '-';
            }
            offset = HexsToChars(guidChars, offset, this._c >> 8, this._c);
            if (flag)
            {
                guidChars[offset++] = '-';
            }
            offset = HexsToChars(guidChars, offset, this._d, this._e);
            if (flag)
            {
                guidChars[offset++] = '-';
            }
            offset = HexsToChars(guidChars, offset, this._f, this._g);
            offset = HexsToChars(guidChars, offset, this._h, this._i);
            offset = HexsToChars(guidChars, offset, this._j, this._k);
        }
    }
    return str;
}

调用代码如下:

            var gid = Guid.NewGuid();
            Console.WriteLine(gid.ToString("d"));
            Console.WriteLine(gid.ToString("n"));
            Console.WriteLine(gid.ToString("b"));
            Console.WriteLine(gid.ToString("p"));
            Console.WriteLine(gid.ToString("x"));

2、Enum,Enum重写的ToString()方法,ToString()方法没有使用到IFormatProvidedr接口,如下所示:

 
 
public string ToString(string format, IFormatProvider provider) => 
    this.ToString(format);
public string ToString(string format)
{
    if ((format == null) || (format.Length == 0))
    {
        format = "G";
    }
    if (string.Compare(format, "G", StringComparison.OrdinalIgnoreCase) == 0)
    {
        return this.ToString();
    }
    if (string.Compare(format, "D", StringComparison.OrdinalIgnoreCase) == 0)
    {
        return this.GetValue().ToString();
    }
    if (string.Compare(format, "X", StringComparison.OrdinalIgnoreCase) == 0)
    {
        return InternalFormattedHexString(this.GetValue());
    }
    if (string.Compare(format, "F", StringComparison.OrdinalIgnoreCase) != 0)
    {
        throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification"));
    }
    return InternalFlagsFormat((RuntimeType) base.GetType(), this.GetValue());
}

调用代码如下:

        static void Main(string[] args)
        {
            var a = Type.a;
            //返回常规的字符串,也就是a的字符串形式,输出:a
            Console.WriteLine(a.ToString("G"));
            //返回a的枚举值,输出:1
            Console.WriteLine(a.ToString("D"));
            //返回a的十六进制表现形式,输出:00000001
            Console.WriteLine(a.ToString("X"));
            //返回a的字符串形式,输出:a
            Console.WriteLine(a.ToString("F"));
            Console.ReadKey();
        }
        enum Type
        {
            a = 1,
            b = 2,
            c = 3
        }

猜你喜欢

转载自www.cnblogs.com/GreenLeaves/p/9142755.html