C# 泛型方法返回值

14

我正在学习泛型,对于方法返回值有一个问题。

假设我想要一个泛型方法,即方法签名中所需的泛型部分仅是返回值。该方法始终将以一个字符串作为其参数,但可能会返回 double 或 int 之一。这种情况是否可行?

实际上,我想获取一个字符串,解析其中包含的数字(可以是 double 或 int),然后返回该值。

谢谢。


4
除非你只是为了学习而这么做,否则这将是泛型的低效使用。由于需要提前知道类型,因此最好使用Convert.ToDouble或Convert.ToInt32来完成此特定任务。解析方法无法仅通过查看字符串来"自动地"确定类型。在传递字符串之前,你仍然需要知道类型。 - Joel Etherton
4个回答

16

像这样的内容吗?

void Main()
{
    int iIntVal = ConvertTo<int>("10");
    double dDoubleVal = ConvertTo<double>("10.42");
}

public T ConvertTo<T>(string val) where T: struct
{
    return (T) System.Convert.ChangeType(val, Type.GetTypeCode(typeof(T)));
}

var kvp = ConvertTo<KeyValuePair<int, List<string>>>("1, 2"); 这个怎么样? :) - Benjol
@Benjol: 嗯,System.Convert.ChangeType通常会失败。在编译时无法检查T类型是否可转换,因为“简单”值类型没有通用约束(“struct”约束至少可以防止使用引用类型)。因此,我们将类型验证留给 System.Convert.ChangeType 在运行时处理。 - Maxim Gueivandov

12

如果不将其他类型一起返回,泛型方法无法返回doubleint

例如,我可能有一个Foo类和您的泛型解析方法,没有任何约束,将允许进行以下调用:

Foo result = Parse<Foo>("111");

你能够做的最好的事情就是通过只允许使用struct(值类型)来对你的函数进行限制。
T Parse<T>(string value) where T : struct;

但这将允许所有数字类型,以及任何其他值类型。

您可以通过接口类型进行约束,但是在doubleint上没有INumeric接口,因此您有点卡住了。

唯一能做的事情就是如果传入错误类型,则抛出异常 - 通常并不令人满意。

在这种情况下,最好的方法是放弃泛型并使用单独命名的方法。

double ParseDouble(string value);
int ParseInteger(string value);

当然,这并不能帮助你学习泛型。抱歉。


感谢你的回答。我原本想使用泛型,因为认为只需要一个方法可能会更有效率。显然情况并非如此,我最好继续使用我目前使用的两种方法。谢谢。 - Darren Young

9

是的,这是可能的。

例子:

public T ParseValue<T>(String value) { 
    // ...
}

2
您可以这样做...
   public TResult Parse<TResult>(string parameter)
    {
     /* do stuff */
    }

然后像这样使用它...

int result = Parse<int>("111");

那么这将取决于你在解析方法中的实现。

希望能帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接