3

我正在尝试编写验证方法。例如:对于 double 它看起来像这样:

   protected bool ValidateLoopAttributes(string i_value, double i_threshold)
       {
        double result;
        if (!(double.TryParse(i_value, out result) && result >= i_threshold))
        {
            return false;
        }
        return true;
    }

是否可以这样写:

     protected bool ValidateLoopAttributes<T>(string i_value, T i_threshold)

然后使用类似的东西

             T.GetType().TryParse() // how can i use here the type's methods??

使用 switch/if 语句是唯一的方法吗?例如:

    If (T.GetType() is int) 
        Int32.TryParse(i_threshold)

有没有更优雅的方式?

4

4 回答 4

1

试试这个:

static class Ext
{
    public static bool TryParse<T>(string s, out T value)
    {
        TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
        try
        {
            value = (T)converter.ConvertFromString(s);
            return true;
        }
        catch
        {
            value = default(T);
            return false;
        }
    }
    public static bool ValidateLoopAttributes<T>(string i_value, T i_threshold) 
           where T : IComparable
    {
        T outval;
        if (TryParse<T>(i_value, out outval))
            return outval.CompareTo(i_threshold) >= 0;
        else return false;
    }
}

我的回答使用了 Marc Gravell 从这里获取的回答。
有了这个你可以做

bool b1 = Ext.ValidateLoopAttributes<int>("5", 4);
bool b2 = Ext.ValidateLoopAttributes<double>("5.4", 5.5d);

如果您觉得它有用,您还可以使用扩展方法

public static bool ValidateLoopAttributes<T>(this string i_value, T i_threshold) 
       where T : IComparable { }

这导致您使用

bool b1 = "5".ValidateLoopAttributes<int>(4);
bool b2 = "5.4".ValidateLoopAttributes<double>(5.5d);
于 2012-04-13T09:10:13.393 回答
1
public static bool ValidateLoopAttributes<T>(string value, T threshold)
    where T : IComparable
{
    try
    {
        var parseMethod = typeof(T).GetMethod("Parse", new[] {typeof (string)});
        var result = (T) parseMethod.Invoke(null, new object[] {value});
        return result.CompareTo(threshold) < 0;
    }
    catch (Exception)
    {
        return false;
    }
}

显然,这只适用于具有静态 Parse 方法的类型。

于 2012-04-13T09:31:32.757 回答
1

目前,您在方法中混合了两件事 - 解析和业务规则。考虑你调用ValidateLoopAttributes(value, 4)它并返回false. 可能的原因:

  1. 字符串不包含值。例如空,一些字符等。
  2. 字符串不包含整数值。例如,它具有双重价值。
  3. 字符串包含整数值,但超过阈值。
  4. 没有为您的类型定义转换器。

在第一种情况下,您的源中有无效数据。在第二种情况下,您的代码无效,应该使用 double 代替。在第三种情况下,代码还可以,但业务规则被破坏了。在最后一种情况下(对于双精度或整数来说不是这种情况,但是如果您编写没有类型限制的通用代码,则允许其他人以任何类型调用它)代码中也存在问题。

所以,考虑分离业务规则和解析数据。

Foo foo = Parse(xml);
RunBusinessRules(foo); 
于 2012-04-13T09:35:41.570 回答
0

可以尝试使用这样的东西来检查这是否是一个整数:

public static bool IsNumericValue(string val, System.Globalization.NumberStyles NumberStyle)
{
    double result;
    return Double.TryParse(val,NumberStyle,
        System.Globalization.CultureInfo.CurrentCulture,out result);
}

很快

 IsNumericValue("1.2", System.Globalization.NumberStyles.Integer) // FALSE 

和上

 IsNumericValue("12", System.Globalization.NumberStyles.Integer)  // TRUE

请注意,在我使用的这个示例中,如果它们不同,请CurrectCulture根据您的需要进行调整。

于 2012-04-13T09:01:24.150 回答