【问题标题】:Converting 'anything' to string via TypeConverters通过 TypeConverters 将“任何东西”转换为字符串
【发布时间】:2015-10-03 18:10:36
【问题描述】:

我正在尝试创建一个实用方法,该方法使用TypeConverter 将任意类型的值转换为另一种类型。但是,当尝试将某些内容转换为字符串时,TypeConverter 总是失败。

private bool TryConvertType(object value, Type targetType, out object result) {
    result = null;
    if(value == null)
        return false;

    try {

        if(targetType.IsInstanceOfType(value)) {
            result = value;
            return true;
        }

        var typeConverter = TypeDescriptor.GetConverter(targetType);
        if(typeConverter.CanConvertFrom(value.GetType())) {
            result = typeConverter.ConvertFrom(value);
            return true;
        }
        ...

给定 value 作为类型 bool 和 targetType string,方法 .CanConvertFrom() 总是返回 false。为什么不能从boolean 值创建string?还是我在这里遗漏了什么?

【问题讨论】:

  • 需要有关错误的更多信息。但首先一个问题 .ToString() 有什么问题??
  • @BillRuhl 错误很简单:TypeDescriptor 无法从布尔值转换为字符串。 (.CanConvertFrom() 返回 false)。而已。而且,如您所见, utlity 方法的想法是将任何值转换为另一种类型。我只是在这个例子中使用了字符串 bool。
  • 嗯......我再次不确定你之后的内容,但 C# 已经完成了所有这些,如果你在 bool 值上调用 .ToString() 它将返回“true”或“false”。对 TypeDescriptor 类本身并不确定,但您面临的一件事是内存分配。将布尔值转换为字符串是一回事,您只会得到真或假,但从字符串到布尔值将不起作用......

标签: c# .net reflection types type-conversion


【解决方案1】:

您正在向后使用TypeConverter。或者更确切地说,您正在尝试在 bool 上使用 string TypeConverter:

var typeConverter = TypeDescriptor.GetConverter(targetType);

这为您提供了字符串的TypeConverter,但您希望转换的变量是bool。您还想使用CanConvertTo / ConvertTo 进行实际转换:

// get bool type TypeConverter
var typeConverter = TypeDescriptor.GetConverter(value.GetType());
// can it convert a bool to string?
if (typeConverter.CanConvertTo(targetType))
{
    // joy!
    result = typeConverter.ConvertTo(value, targetType);
    return true;
}

测试代码:

if (TryConvertType(b, t, out result))
    Console.WriteLine(result.ToString());

输出:

是的

当然,ToString() 已经可以处理几乎任何事情。

【讨论】:

  • 向后使用 TypeConverter。怎么知道这甚至是可能的?使用StringConverter 转换FROM boolean TO string 听起来与使用BooleanConverter 转换TO相同> string 来自 boolean。 .NET 开发人员在设计那个令人困惑的 API 时在想什么?无论如何,它现在可以工作了,非常感谢你。
  • 字符串是特殊的。请记住,每一种类型都有一个字符串表示。如果不是这样,我们将无法在屏幕上显示它们。这就是为什么 object 有一个 ToString() 函数。将这些“到字符串”转换放在 StringConverter 中确实会使其成为一个非常大的类,并且一旦您创建了一个新类,它就会过时。这些“到字符串”转换的正确位置是在相关类型的 TypeConverter 中。在这种情况下,BooleanConverter。
【解决方案2】:

我不知道具体原因,但查看StringConverter (here) 的来源

public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
            if (sourceType == typeof(string)) {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }

对于除字符串以外的任何类型,它都遵循基本TypeConverter 类;我根本无法让 CanConvertFrom 为任何类型返回 true!我不知道为什么会这样,但你总是可以这样做:

try
{
     var convertedValue = Convert.ChangeType(value,targetType);
     return convertedValue;
}
catch(FormatException fex)
{
    //can't convert for whatever reason.
}

作为奖励,我将发出强制性警告,即从一种类型疯狂转换为另一种类型可能会导致爆炸,可能会有更好的设计来实现您的目标,等等 :)

【讨论】:

    猜你喜欢
    • 2013-06-02
    • 2014-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 2015-01-05
    • 2019-02-18
    相关资源
    最近更新 更多