通用字符串解析器

时间:2011-06-16 20:42:20

标签: c# c#-4.0

我需要一个可以返回从字符串

解析的值的泛型方法
public T GetDefaultValue<T>(){
    // if typeof(T) is Double it should try to parse some string (supposedly which's been read from DB), 
    // and return Double value, or if typeof(T) is Int, then it should parse the string 
    //into Int, and finally if typeof(T) is a string, then no parsing is needed.
}

UPD ... 为什么我不能检查T是否是某种类型并相应地使用Parse方法?

5 个答案:

答案 0 :(得分:2)

Convert.ChangeType可用于进行转化。

public T Parse<T>(string input)
{
     return (T)Convert.ChangeType(input, typeof(T));
}

int x = Parse<int>("1");
double y = Parse<double>("1.0");
string z = Parse<string>("hey");

请注意,即使要完成这项工作,您也要指定类型?使用int.Parse(或TryParse),double.Parse等节省了多少钱?

既然你提到你的输入可能来自数据库,并且仍然知道即使使用上述方法你也必须指定类型参数,我会鼓励你(a)了解并信任您的类型;(b)使用现有功能从数据源获取值。无需将某些内容转换为字符串,然后将其转换回您希望的任何数据类型。

int x = myDataRow.Field<int>("Column1"); // or
int x = (int)myDataRow["Column1"];

如果数值在数据库中可以为空,这也支持。

int? x = myDataRow.Field<int?>("Column1"); // or
int x = myDataRow.Field<int?>("Column1").GetValueOrDefault(); // normalize nulls to 0

答案 1 :(得分:1)

使用泛型有什么意义?通过检查实际类型,您将失去泛型的所有好处。

只有三个重载,一个用于int,一个用于double和(可能不需要)string

答案 2 :(得分:1)

你可以在没有泛型的情况下做这样的事情。当你需要的只是针时,为什么要使用剑

class Test
    {
        public string ReadFromDb()
        {
            //Do your db work here
            return "";
        }

        public bool GetDefaultValue(ref int t1)
        {
            t1 = Int32.Parse(ReadFromDb());
            return true;
        }

        public bool GetDefaultValue(ref double t1)
        {
            t1 = Double.Parse( ReadFromDb() );
            return true;
        }

        public bool GetDefaultValue(ref string t1)
        {
            t1 = ReadFromDb();
            return true;
        }
    }

答案 3 :(得分:1)

我只会像

那样进行字符串扩展
public static int xToInt(this string source, int alternate = 0)
{
   int result;
   return (int.TryParse(source, out result) ? result : alternate);
}

然后只为Double创建一个,然后你可以通过

来使用它
int someNumber  = "123456".xToInt();
int someNumber2 = "omg!".xToInt(333);

答案 4 :(得分:1)

我编写了泛型方法,使用反射来搜索适当的Parse方法并调用它。但是,如果您希望将string转换为string,那么它们将无效,因为string没有Parse方法。因此,您需要为string添加一个特殊情况。

我不明白为什么你的函数被称为GetDefaultValue。为什么不ParseTryParseConvertFromString或类似的东西?当看到一个名为GetDefaultValue的函数时,我没有想到解析函数。

检查这个老问题: Is it possible to make a generic number parser in C#?有几个相关答案。


我的回答是:

我编写了一些代码,使用反射来查找类型上的Parse / TryParse方法,并从泛型函数中访问这些方法:

private static class ParseDelegateStore<T>
{
    public static ParseDelegate<T> Parse;
    public static TryParseDelegate<T> TryParse;
}

private delegate T ParseDelegate<T>(string s);
private delegate bool TryParseDelegate<T>(string s, out T result);


public static T Parse<T>(string s)
{
    ParseDelegate<T> parse = ParseDelegateStore<T>.Parse;
    if (parse == null)
    {
        parse = (ParseDelegate<T>)Delegate.CreateDelegate(typeof(ParseDelegate<T>), typeof(T), "Parse", true);
        ParseDelegateStore<T>.Parse = parse;
    }
    return parse(s);
}

public static bool TryParse<T>(string s, out T result)
{
    TryParseDelegate<T> tryParse = ParseDelegateStore<T>.TryParse;
    if (tryParse == null)
    {
        tryParse = (TryParseDelegate<T>)Delegate.CreateDelegate(typeof(TryParseDelegate<T>), typeof(T), "TryParse", true);
            ParseDelegateStore<T>.TryParse = tryParse;
    }
    return tryParse(s, out result);
}

https://github.com/CodesInChaos/ChaosUtil/blob/master/Chaos.Util/Conversion.cs

但是我没有对它们进行过多的测试,所以它们可能会因为每种类型都有一些错误/不能正常工作。错误处理也有点缺乏。

它们没有文化不变解析的重载。所以你可能需要添加它。