以字符串格式从示例列表中手动推断变量类型

时间:2014-02-05 19:32:05

标签: c# type-inference

我从文件中读取了List<string>个样本数据点。我正在寻找一种方法来推断列表中的示例最合适的类型。例如,想象一下列表的初始化如下:

var samples = new List<string>()
    {
        "1",
        "2",
        "2.01"
    };

我正在寻找一个接受此列表并返回System.double的方法。我想知道是否有任何我可以使用的内部C#方法。我的数据可以是int,double或一个字符串,所以我总是可以尝试将它们转换为int,如果失败则将其转换为double,如果失败则返回所有元素System.string。有没有更简单的方法呢?

3 个答案:

答案 0 :(得分:0)

方法应该有一个单一的返回类型,有很多方法可以解决这个问题,但最好还是返回一个字符串,只要你在调用的地方处理字符串,就可以了。例如。

String s=method(samples);
int i;
try
{
     i=s.ToDecimal();
}
catch (FormatException e)
{
    Console.WriteLine("Input string is not a sequence of digits.");
}
catch (OverflowException e)
{
    Console.WriteLine("The number cannot fit in an Int32.");
}  

答案 1 :(得分:0)

据我所知,没有任何内置功能,但您可以编写自己的内容:

public delegate bool TryParseDelegate<T>(string str, out T value);

public static Tuple<Func<string, bool>, Type> ParsesAs<T>(TryParseDelegate<T> d)
{
    Func<string, bool> f = s =>
    {
        T val;
        return d(s, out val);
    };

    return Tuple.Create(f, typeof(T));
}

public static Type FindBestType(List<string> input)
{
    var parsers = new List<Tuple<Func<string, bool>, Type>>
    {
        ParsesAs<int>(int.TryParse),
        ParsesAs<double>(double.TryParse)
    };

    int i = 0;
    foreach (string str in input)
    {
        while (i < parsers.Count && !parsers[i].Item1(str))
        {
            i++;
        }
        if (i == parsers.Count) break;
    }

    return i == parsers.Count ? typeof(string) : parsers[i].Item2;
}

答案 2 :(得分:0)

假设它只是int / double / string你可以做这样的事情。它没有以任何方式优化。只是直截了当的东西可能会让你走上正轨。

public static Type InferType(List<string> samples)
{
    Type stringType= typeof(string);
    Type intType = typeof(int);
    Type doubleType = typeof(double);
    List<Type> types = new List<Type>();
    for (int i = 0; i < samples.Count; i++)
    {
        int intRepresentation;
        double doubleRepresentation;
        if (int.TryParse(samples[i], out intRepresentation))
        {
            types.Add(intType);
        }
        else if (double.TryParse(samples[i], out doubleRepresentation))
        {
            types.Add(doubleType);
        }
        else
        {
            types.Add(stringType);
            break;
        }
    }

    return types.Any(e => e == stringType) ? stringType :
        types.Any(e => e == doubleType) ? doubleType :
        intType;
}