C# 通用字符串分析器

C# 通用字符串分析器,c#,c#-4.0,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 str

我需要一个可以返回从字符串解析的值的通用方法

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.
}
public T GetDefaultValue(){
//如果typeof(T)是Double,它应该尝试解析一些字符串(假定是从DB读取的),
//并返回双精度值,或者如果typeof(T)是Int,那么它应该解析字符串
//最后,如果typeof(T)是字符串,则不需要解析。
}

UPD…为什么我不能检查t是否是某个特定类型并相应地使用Parse方法

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


只有三个重载,一个用于
int
,一个用于
double
和(可能不需要的)
string
,使用泛型有什么意义?通过检查实际类型,您将失去泛型的所有好处


只要有三个重载,一个用于
int
,一个用于
double
和(可能不需要的)
string
,您可以在没有泛型的情况下执行类似的操作。你只需要一根针,为什么还要用剑呢

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;
        }
    }

您可以在没有泛型的情况下执行类似的操作。你只需要一根针,为什么还要用剑呢

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;
        }
    }

我只需要像这样做字符串扩展

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);

我只需要像这样做字符串扩展

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);

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? x = myDataRow.Field<int?>("Column1"); // or
int x = myDataRow.Field<int?>("Column1").GetValueOrDefault(); // normalize nulls to 0
int?x=myDataRow.Field(“Column1”);//或
int x=myDataRow.Field(“Column1”).GetValueOrDefault();//将空值规格化为0

转换。可以使用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? x = myDataRow.Field<int?>("Column1"); // or
int x = myDataRow.Field<int?>("Column1").GetValueOrDefault(); // normalize nulls to 0
int?x=myDataRow.Field(“Column1”);//或
int x=myDataRow.Field(“Column1”).GetValueOrDefault();//将空值规格化为0

我编写了通用方法,使用反射搜索适当的
解析
方法并调用它。但是如果您想将
string
转换为
string
,它们将不起作用,因为
string
没有
Parse
方法。因此,您需要为
string
添加一个特例

我也不明白为什么要调用函数
GetDefaultValue
。为什么不
Parse
TryParse
ConvertFromString
或类似的东西呢?当看到名为
GetDefaultValue
的函数时,我不会想到解析函数

勾选这个老问题: 这有几个相关的答案


我的老回答是:

我编写了一些代码,使用反射查找类型上的
解析
/
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);
}
私有静态类ParseDelegateStore
{
公共静态解析;
公共静态TryParseDelegate TryParse;
}
私有委托T ParseDelegate(字符串s);
私有委托bool TryParseDelegate(字符串s,out T结果);
公共静态T解析(字符串s)
{
ParseDelegate parse=ParseDelegateStore.parse;
if(parse==null)
{
parse=(ParseDelegate)Delegate.CreateDelegate(typeof(ParseDelegate),typeof(T),“parse”,true);
ParseDelegateStore.Parse=Parse;
}
返回解析;
}
公共静态bool TryParse(字符串s,out T结果)
{
TryParseDelegate tryParse=ParseDelegateStore.tryParse;
if(tryParse==null)
{
tryParse=(TryParseDelegate)Delegate.CreateDelegate(typeof(TryParseDelegate),typeof(T),“tryParse”,true);
ParseDelegateStore.TryParse=TryParse;
}
返回tryParse(s,out结果);
}

但是我没有对它们进行过太多的测试,所以它们可能有一些错误/不能正确地处理每种类型。错误处理也有点缺乏


它们没有用于区域性不变解析的重载。所以您可能需要添加它。

我编写了一些通用方法,它们使用反射来搜索适当的
解析
方法并调用它。但是如果您想将
string
转换为
string
,它们将不起作用,因为
string
没有
Parse
方法。因此,您需要为
string
添加一个特例

我也不明白为什么要调用函数
GetDefaultValue
。为什么不
Parse
TryParse
ConvertFromString
或类似的东西呢?当看到名为
GetDefaultValue
的函数时,我不会想到解析函数

勾选这个老问题: 这有几个相关的答案


我的老回答是:

我编写了一些代码,使用反射查找类型上的
解析
/
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);
}
私有静态类ParseDelegateStore
{
公共静态解析;
公共静态TryParseDelegate TryParse;
}
私有委托T ParseDelegate(字符串s);
私有委托bool TryParseDelegate(字符串s,out T结果);
公共静态T解析(字符串s)
{
ParseDelegate parse=ParseDelegateStore.parse;
if(parse==null)
{
parse=(ParseDelegate)Delegate.CreateDelegate(typeof(ParseDelegate),typeof(T),“parse”,true);
ParseDelegateStore.Parse=Parse;
}
返回解析;
}
公共静态bool TryParse(字符串s,out T结果)
{
TryParseDelegate tryParse=ParseDelegateStore.tryParse;
if(tryParse==null)
{
tryParse=(TryParseDelegate)Delegate.CreateDelegate(typeof(TryParseDelegate),typeof(T),“tryParse”,true);
ParseDelegateStore.TryParse=TryParse;
}
返回tryParse(s,out结果);
}

但是我没有对它们进行太多的测试,s