【问题标题】:ChangeType, Convert - Converting from one type to anotherChangeType, Convert - 从一种类型转换为另一种类型
【发布时间】:2025-12-29 23:05:10
【问题描述】:

我查看了似乎在 .NET 框架上可用的各种选项(我认为)。特别是,我看过 1.类型转换器 2. 转换.Toxxx 3. 转换.ChangeType

由于某种原因,它们中的每一个都不适合我。我很惊讶 .NET 框架中似乎没有针对此类事情的解决方案。我假设我不是唯一需要这个的人;)

这就是我想要做的。本质上,我有一堆在应用程序中使用的 html 表单。这些表单允许用户输入数据(显然),我需要将这些数据提取为各种数据类型。

这些数据类型是简单类型、原始类型、值类型、引用类型和自定义引用类型。换句话说: 1. Int32、Int64、double、decimal、DateTime 等。 2. Int32[]、double[]、string[] 以及其他可能的原始类型数组 3.具有上述类型作为属性的各种自定义DTO对象。

“输入”通常采用字符串的形式,因为我在 Http 领域。为了让您了解为什么现有解决方案对我不起作用,请查看以下需要转换的“字符串”输入

  1. “1,234”-> Int32
  2. “$1,234”->Int32
  3. “$ 1,234”-> Int32
  4. "" -> Int32
  5. "1,2,3,4,5" ->Int32[]
  6. “0”或“假”或“假”或“关”->布尔假

我知道如何手动转换每种情况,但我正在寻找我错过的框架的一部分,或者是处理上面列出的输入类型的体面解决方案。

【问题讨论】:

  • 我认为您没有找到所需内容的原因是您所描述的是用于转换任意数量数据类型的任意数量的“规则”。在框架级别尝试这样做根本不可行,因为总会有一些边缘情况不起作用。我要做的是创建一个特殊的转换类,它知道这些特殊情况并处理它们(在默认为 TypeConverter.ChangeType 等之前)。然后,您可以在任何需要的地方重用该代码。

标签: .net types


【解决方案1】:

杰基,

这是 Web 开发世界中非常常见的要求,正如您所指出的,没有内置的方法可以实现这一点,而且在最简单的情况下也存在不足。

@Chris 这些规则不是任意想象的。事实上,它们在处理用户输入时非常常见,尤其是在网络上。事实上,鉴于 ASP.NET 中的复选框会返回开/关(出于某种原因),布尔转换也很常见。

您有几个选择。一种是简单的方法,另一种是可扩展的解决方案。这一切都始于您希望在应用程序中使用此功能的方式。由于您没有详细说明您目前正在做什么或您希望如何做,因此我冒昧地做了一些假设。

主要假设是这些值通过 Request.Form 或 Request.QueryStrings(两者都是 NameValueCollections,可以为给定名称保存多个值)提供给您。

假设您想要一个名为 ChangeType 的方法,该方法给出了参数名称,并且您想要将其更改为的 Type 将返回值作为所需类型。所以方法签名可能如下所示:

public T ChangeType<T>(string parameterName, T defaultValue = default(T))

所以你可以像这样使用它:

int someId = ChangeType<int>("id", -1);

因此变量 someId 的值将是从 Request.Form 或 Request.QueryStrings 中提取的值,以 int 形式(如果存在)或 -1 如果不存在。

更完整的实现如下:

    static T ChangeType<T>(string value) where T: struct
{
  Type typeOft = typeof(T);
  if (String.IsNullOrEmpty(value.Trim()))
    return default(T);
  if (typeOft == typeof(Int32))
    return (T)ConvertToInt32(value);
  else if (typeOft == typeof(Int64))
    return (T)ConvertToInt64(value);
  else if (typeOft == typeof(Double))
    return (T)ConvertToDouble(value);
  else if (typeOft == typeof(Decimal))
    return (T)ConvertToDecimal(value);
  return default(T);
}

static object ConvertToInt32(string value)
{
  return Int32.Parse(value,
    NumberStyles.Currency ^ NumberStyles.AllowDecimalPoint);
}

static object ConvertToInt64(string value)
{
  return Int64.Parse(value,
    NumberStyles.Currency ^ NumberStyles.AllowDecimalPoint);
}

static object ConvertToDouble(string value)
{
  return Double.Parse(value, NumberStyles.Currency);
}

static object ConvertToDecimal(string value)
{
  return Decimal.Parse(value, NumberStyles.Currency);
}

如果您需要能够处理更多类型,只需实现所需的方法(例如 ConvertToInt32)并在 ChangeType&lt;T&gt; 方法中添加另一个 else 条件即可。

现在,如果您正在寻找一种可扩展的解决方案,以便您可以添加额外的功能而无需修改主要代码并且能够处理您自己的自定义类型,那么请查看我的这篇博文。 [ChangeType – 在 C# 中更改变量的类型][1] http://www.matlus.com/2010/11/changetypet-changing-the-type-of-a-variable-in-c/

希望对您有所帮助。

【讨论】:

  • 谢谢!这正是我一直在寻找的。简单的解决方案很好,但可扩展的解决方案非常好。也感谢您的文章和代码。我已经将它插入到我的代码中,它就像一个魅力(带有一些命名空间修改)。
  • 恐怕我可以投票赞成你的答案,因为我还没有声望。
【解决方案2】:

所有原始类型(例如 int 和 bool)都有一个 TryParse static method 供您使用。这将为您完成 Int32 的工作:

Int32 temp = 0;
Int32.TryParse(myStringInput, out temp);

TryParse() 返回一个布尔值,指示解析是否成功,因此您可以对其进行测试并根据需要采取行动,或者像我上面所做的那样做,如果TryParse 有一个默认值失败。 TryParse 特别有用,因为它在失败时不会抛出异常(它只是返回false)。

bool.TryParse() 不会直接将数字 0 转换为 false - 您需要先将其转换为字符串:

bool x = true;
bool.TryParse(0.ToString(), out x);
Console.WriteLine("x is {0}", x);

将字符串值 offon 转换为布尔值需要您自己的函数来解释它。

【讨论】:

  • 笨蛋,感谢您的回复。我确实知道如何将所有示例转换为我需要的类型。我正在寻找已经这样做的 .net 类/实用程序或非常通用和/或可扩展的解决方案。