C#将格式化字符串(31.2k)转换回数字(31240)

C#将格式化字符串(31.2k)转换回数字(31240),c#,string,formatting,format,number-formatting,C#,String,Formatting,Format,Number Formatting,假设我有以下代码: int i = 31240; string Number = ((double)i / 1000).ToString("0.#k"); 我将这个结果作为数字31,2k的字符串 现在,我想做完全相反的事情,就是把这个字符串“31,2k”带回到31240,甚至31200,但我不知道怎么做。。。 有什么想法吗 有人说那是不可能的。 但最终我找到了实现目标的完美方法。我为那些愿意知道的人发布了解决方案。 使用简单,允许进行两种转换: 千,示例:45831 45,8k 45831

假设我有以下代码:

int i = 31240;
string Number = ((double)i / 1000).ToString("0.#k");
我将这个结果作为数字31,2k的字符串

现在,我想做完全相反的事情,就是把这个字符串“31,2k”带回到31240,甚至31200,但我不知道怎么做。。。 有什么想法吗


有人说那是不可能的。 但最终我找到了实现目标的完美方法。我为那些愿意知道的人发布了解决方案。 使用简单,允许进行两种转换:

  • 千,示例:45831 45,8k 45831
  • 百万,例如:123852376 123,5m 123852376
我们用
Number.Substring(0,Number.Length-1)
删除
k
,用
double.Parse将其转换为double,乘以1000,最后转换为
int
。事情的顺序很重要!我第一次做
(int)Double.Parse(Number.Substring(0,Number.Length-1))*1000
,它在乘法之前转换为int(所以我得到了31000而不是31200)

我要补充一点,如果我必须写那段代码,如果我使用
Decimal.Parse
而不是
Double.Parse
,我会睡得更好(因此我可以确保不受浮点变化的影响)

我将添加一个更好的方法:

int i2 = int.Parse(Number.Substring(0, Number.Length - 1).Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, string.Empty)) * 100;
这更有趣。我们删除了
k
,就像在另一个方法中一样,但是这次我们也从
字符串中删除了
,并乘以100

有趣的技巧是,我们不是简单地用空字符串替换
,而是得到当前的十进制分隔符(
CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
),然后用空字符串替换它


显然,如果我们在编写原始字符串时使用了另一种区域性(例如,始终良好的
CultureInfo.InvariantCulture
),我们将使用它来获得
NumberDecimalSeparator

,以下是我所经历的解决方案:

public class StringFromInt
{
    public enum FormatStyle
    {
        Kilo = 1000,
        Mega = 1000000
    }
    public int Number;
    public FormatStyle Format
    {
        get
        {
            switch (LimitValueBeforeConversion)
            {
                case 1000: return FormatStyle.Kilo;
                case 1000000: return FormatStyle.Mega;
                default:
                    throw new NotImplementedException("You must implement the code for this kind of value");
            }
        }
        set
        {
            if (value == FormatStyle.Kilo)
            {
                LimitValueBeforeConversion = 1000;
            }
            else if (value == FormatStyle.Mega)
            {
                LimitValueBeforeConversion = 1000000;
            }
        }
    }
    public int LimitValueBeforeConversion
    { get; set; }
    public static implicit operator int(StringFromInt s)
    {
        return s.Number;
    }
    public static implicit operator StringFromInt(int number)
    {
        StringFromInt s = new StringFromInt(number);
        return s;
    }

    #region Constructors
    public StringFromInt(int number, FormatStyle format)
    {
        this.Number = number;
        Format = format;
    }
    public StringFromInt(int number)
        : this(number, FormatStyle.Kilo)
    {
        if (number >= 1000000)
        {
            this.Format = FormatStyle.Mega;
        }
    }
    #endregion

    public override string ToString()
    {
        if (Number >= LimitValueBeforeConversion)
        {
            string formatString = "0.#k";
            switch (Format)
            {
                case FormatStyle.Kilo:
                    formatString = "0.#k";
                    break;
                case FormatStyle.Mega:
                    formatString = "0.#m";
                    break;
                default:
                    throw new NotImplementedException("You must implement the code for this kind of value");
            }
            return ((double)Number / LimitValueBeforeConversion).ToString(formatString);
        }
        else
        {
            return Number.ToString();
        }
    }
}

这是一个测试程序:

class Program
{
    static void Main(string[] args)
    {
        int i = 31240;

        string StringRepresentation = ((double)i / 1000).ToString("0.#k");
        int resultBackWithParse = int.Parse(StringRepresentation.Substring(0, StringRepresentation.Length - 1).Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, string.Empty)) * 100;
        Console.WriteLine("Base number: " + i.ToString());
        Console.WriteLine(new string('-', 35));
        Console.WriteLine("String representation: " + StringRepresentation);
        Console.WriteLine("Int representation With Int.Parse: " + resultBackWithParse.ToString());
        Console.WriteLine();
        StringFromInt MySolutionNumber = i;
        int resultBackWithStringFromInt = MySolutionNumber;
        Console.WriteLine("String representation With StringFromInt: " + MySolutionNumber.ToString());
        Console.WriteLine("Int representation With StringFromInt: " + resultBackWithStringFromInt);

        Console.WriteLine(new string('=', 35) + "\n");
        i = 123456789;
        StringFromInt MyNumber = 123456789;
        int resultBack = MyNumber;
        Console.WriteLine("Base number: " + i.ToString());
        Console.WriteLine(new string('-', 35));
        Console.WriteLine("String representation With StringFromInt: " + MyNumber);
        Console.WriteLine("Int representation With StringFromInt: " + resultBack);

        Console.ReadKey(true);
    }
}

正如您所注意到的,不需要使用“新”初始值设定项,我的意思是不需要执行以下操作:

StringFromInt Number = new StringFromInt(YourNumber)
由于使用隐式运算符,您可以执行以下操作:

StringFromInt Number = YourNumber
我不知道,但我觉得这是个好的开始,你觉得呢

不管怎样,我成功地做到了我想做的,所以对于那些认为这不可能做到的人来说,你看,这是可能的:-)

显然这是可以改进的:这个版本只适用于成千上万的人


问候语

要求tostring和“fromstring”操作使用相同的区域性。一个合理的假设我会说是的,我写问题太快了,因为我考虑过了。不管怎样,你认为有办法回到准确的数字吗?我看到的唯一方法是创建一个类,一个名为StringFromNumber的类,它将保存以前的值。好吧,我想我将继续自定义类,它不会花费很长时间来实现……无论如何,关于我问问题的方式,我将验证这个答案。Thanks@GianT971这不是CSI。。。你不能缩放、增强、拍摄!你必须把它保存在某个地方:-)@GianT971,最后在你的问题中你写了
,甚至写了31200
,所以即使你知道这是不可能的:-)你想从312K得到31240吗?如果原来的数字是31260,你怎么知道31,2k和31,2k之间的区别呢?是的,你肯定是对的,我只是为了这个目的去定制一个类,谢谢你的时间作为一般规则,如果你自己解决它,你在回答中发布解决方案,然后接受它。对不起,你没有解决原来的问题(“也就是说,把这个字符串“31,2k”带回到31240”)你解决了一个不同的难题。我怎样才能漂亮地打印一个数字,并且仍然能够保留数字value@xanatos,我不能做,因为你必须等8个小时才能回答你自己的问题,但我会做的,谢谢你提醒我
StringFromInt Number = YourNumber