如何在运行时转换类型?

21

我的情况应该很简单... 我想要转换 的类型是 始终 'string'。我想要转换为... 可以是许多东西 - ints、DateTimes、... 字符串等。

这将很容易:

string valueToConvertFrom = "123";

int blah = Convert.ToInt32(valueToConvertFrom);

然而...我在运行时不知道我需要转换的值是一个'Int'(或其他类型)。我尝试过以下方法:

string valueToConvertFrom = "123";

Type convertToType = typeof(int);

object blah = Convert.ChangeType(valueToConvertFrom, convertToType);

但这会给我以下错误:"对象必须实现IConvertible。"

我不想通过switch语句和基于类型名称调用"Convert.ToBlah"来解决此问题... 有什么建议吗?


请重新打开并添加您找到的答案,以防将来有人遇到相同或类似的问题 - Steven A. Lowe
1
我关闭这个问题的原因是因为我的代码有一个错误... 我最初从错误的字段中提取数据,而那个字段没有实现IConvertible接口。对两个答案都点赞... "String类实现了IConvertible接口,这段代码本应该可以工作" 这是正确的。但是Asher的解决方案很棒,我学到了新东西(而且它是一个非常干净的解决方案)。再次感谢! - Timothy Khouri
3个回答

30

使用TypeConverter是最简洁的方法。您可以通过调用TypeDescriptor.GetConverter来获取类型转换器的实例,然后使用该实例进行转换。

string valueToConvertFrom = "123";

Type convertToType = typeof(int);

TypeConverter tc =  TypeDescriptor.GetConverter(convertToType);             

object blah =tc.ConvertFromString(valueToConvertFrom);

2
Asher的答案不适用于Silverlight(Web或WP7x),因为TypeDescriptor在其中不可用。此外,TypeDescriptor仅为已定义TypeConverter的Type返回TypeConverter,这并不自动适用于大多数Types。而且,TypeDescriptor返回的TypeConverter仅为给定Type定义的第一个TypeConverter。因此,至少不能通常依赖TypeDescriptor进行转换方案。 - Mark Jones
1
还要记住,TypeConverter不仅是一个抽象基类,如果您将其用于自定义类转换,则需要进行自定义实现,而且它相对较慢,因为它是基于反射/发现的机制。 - Mark Jones
有人能否重申或提供更多信息,如果在自定义类(比如Customer或Orders)上使用TypeConverter,那么该类将必须实现IConvertable才能正常工作?如果是的话,我仍然不知道如何使用实现的方法来在自定义类型之间进行转换。 - atconway

5
蒂莫西的问题,总体上应用于.NET类型转换问题,是一个非常大的问题。虽然在特定的已知类型场景下,转换策略有些直截了当,但不幸的是,在任何.NET实现中,都没有通用的策略可以在运行时从任意一种类型转换为另一种类型,也没有来自Redmond的此类策略即将推出。但是,微软提供了一些关于类型转换的好指南,包括: 我在我的系统中也遇到了同样的问题,作为解决方案,我将所有标准策略合并到一个方法中。这个问题的范围很广,相关的转换策略也是多种多样的,因此这个合并的方法只能在完整的技术文章中进行介绍。然而,我在这里提供了我的方法文档副本,希望这可以帮助您对您需要解决的整体要求有一个牢固的理解,如果您想开发类似的通用解决方案。以下是我的文档链接: 希望这可以帮助到您,
马克

5

String类实现了IConvertible接口,这段代码应该可以正常工作。您的目标是哪个版本的.NET?

object o = Convert.ChangeType( str, convertToType );

此外,你提到的大多数类型都实现了Parse方法,所以最好的选择可能是像这样做。
Type convertToType = ...;
MethodInfo mi = convertToType.GetMethod("Parse", BindingFlags.Static);
object blah;
if(mi != null)
{
    blah = mi.Invoke(null, new object[]{valueToConvertFrom});
}
else
{
    // the type doesn't implement the Parse method, handle it another way :/
}

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