2

我正在尝试创建一个像这样的通用函数,我打算用基本类型实例化它,主要是 DateTime、int 和 string。

static T MyParameter<T>(string value, T defaultValue)
{
    return value.StartsWith("$$") ? defaultValue : T.Parse(value);
}

这不会编译,因为不能保证 T 将具有“Parse”。

有没有“直接”的方式来实现它?(我的意思是,避免反射或委托做脏活)。

我找不到任何可以解决问题的 T 约束。

4

3 回答 3

6

您可以传入通用案例​​的 parse 方法:

static T MyParameter<T>(string value, T defaultValue, Func<string, T> parse)
{
    return value.StartsWith("$$") ? defaultValue : parse(value);
}

但为了方便起见,您可能希望为您计划使用的最常见类型提供重载:

static int MyParameter(string value, int defaultValue)
{
    return MyParameter(value, defaultValue, int.Parse);
}
static DateTime MyParameter(string value, DateTime defaultValue)
{
    return MyParameter(value, defaultValue, DateTime.Parse);
}
static string MyParameter(string value, string defaultValue)
{
    return MyParameter(value, defaultValue, x => x);
}

如果你真的不喜欢这个,你可以使用反射,虽然我不推荐它:

static T MyParameter<T>(string value, T defaultValue)
{
    if (value.StartsWith("$$"))
    {
        return defaultValue 
    }

    var method = typeof(T).GetMethod("Parse", new[] { typeof(string) });
    return (T)method.Invoke(null, new[] { value });
}
于 2013-10-07T20:42:25.410 回答
2

在泛型上使用约束怎么样?

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

所以你的方法变成:

static T MyParameter<T>(string value, T defaultValue) where T : IParseable
{
    return (T)(value.StartsWith("$$") ? defaultValue : defaultValue.Parse(value));
}

当然这意味着所有使用的类型都必须实现 IParseable。

于 2013-10-07T20:55:58.750 回答
1

这应该这样做:

static T MyParameter<T>(string value, T defaultValue)
{
    return (T) (value.StartsWith("$$") ? defaultValue : Convert.ChangeType(value, typeof (T)));
}
于 2013-10-07T20:50:07.880 回答