在C#泛型类型上强制执行任意功能

时间:2013-10-07 20:38:17

标签: c# generics

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

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

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

有没有“直接”的方式来实现它? (我的意思是,避免反思或委托进行肮脏的工作)。

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

3 个答案:

答案 0 :(得分:6)

您可以传递通用案例的解析方法:

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

答案 1 :(得分: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。

答案 2 :(得分:1)

这应该这样做:

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