TypeDescriptor CanConvertFrom Ошибка?или я делаю это неправильно? - PullRequest
1 голос
/ 15 декабря 2010

Это метод расширения, взятый из http://dnpextensions.codeplex.com/.

Я понимаю, что строка "test" не является числовой строкой ...

Я понимаю, что GetConverter (targetType) имеет тип int ...

Я не понимаю, почему он говорит, что он может преобразовывать строки ... но он терпит неудачу ...

/// <summary>
///     Converts an object to the specified target type or returns the default value.
/// </summary>
/// <typeparam name = "T"></typeparam>
/// <param name = "value">The value.</param>
/// <param name = "defaultValue">The default value.</param>
/// <returns>The target type</returns>
public static T ConvertTo<T>(this object value, T defaultValue)
{
    if (value != null)
    {
        var targetType = typeof(T);
        var valueType = value.GetType();

        if (valueType == targetType) return (T)value;

        var converter = TypeDescriptor.GetConverter(value);
        if (converter != null)
        {
            if (converter.CanConvertTo(targetType))
                return (T)converter.ConvertTo(value, targetType);
        }

        converter = TypeDescriptor.GetConverter(targetType);
        if (converter != null)
        {
            if (converter.CanConvertFrom(valueType))
                return (T)converter.ConvertFrom(value);
        }
    }
    return defaultValue;
}

    [TestMethod]
    public void TestConvertToWillFail()
    {
        // Arrange
        var value = "test";

        // Act
        var result = value.ConvertTo<int>();

        // Assert
        result.Should().Equal(0);
        result.Should().Not.Equal(value);
    }

    [TestMethod]
    public void TestConvertToShouldPass()
    {
        // Arrange
        var value = 123;
        var stringValue = "123";

        // Act
        var stringResult = stringValue.ConvertTo<int>();

        // Assert
        stringResult.Should().Equal(value);
        stringResult.Should().Not.Equal(0);
    }

Примечание. Следует () с веб-сайта Should.codeplex.com


Исключение из теста:

Тест не является допустимым значением для Int32.

Ответы [ 3 ]

6 голосов
/ 15 декабря 2010

Что ваш метод делает во втором вызове:

  • Получите StringConverter
  • Спросите его, может ли он преобразовать в целые числа - он отвечает нет
  • Получите IntegerConverter
  • Спросите его, можно ли преобразовать из строки - он отвечает да
  • Попросите преобразовать предоставленное значение («тест»)) - и вот где он взрывается, так как «test» действительно недопустимо для Int32.

Методы CanConvertFrom/To предназначены только для проверки того, имеет ли смысл вызов, а небудет ли преобразование успешным, поскольку CanConvert работает только на уровне типа

Существуют строки, которые преобразуются в действительные целые числа, но это не означает, что все строки являются действительными целыми числами, поэтому ConvertFrom/To будет выбрасыватьисключения, даже если CanConvert возвращает true.

1 голос
/ 16 декабря 2010

Это моя работа.Пожалуйста, дайте мне знать, если есть лучшая версия этого.

/// <summary>
///     Converts an object to the specified target type or returns the default value.
/// </summary>
/// <typeparam name = "T"></typeparam>
/// <param name = "value">The value.</param>
/// <param name = "defaultValue">The default value.</param>
/// <returns>The target type</returns>
public static T ConvertTo<T>(this object value, T defaultValue)
{
    if (value != null)
    {
        try
        {
            var targetType = typeof(T);
            var valueType = value.GetType();

            if (valueType == targetType)
                return (T)value;

            var converter = TypeDescriptor.GetConverter(value);
            if (converter != null)
            {
                if (converter.CanConvertTo(targetType))
                    return (T)converter.ConvertTo(value, targetType);
            }

            converter = TypeDescriptor.GetConverter(targetType);
            if (converter != null)
            {
                if (converter.CanConvertFrom(valueType))
                {

                    return (T)converter.ConvertFrom(value);

                }
            }
        }
        catch (Exception e)
        {
            return defaultValue;
        }
    }
    return defaultValue;
}
0 голосов
/ 15 декабря 2010

ConvertTo может выдавать исключения , если не может выполнить преобразование ... даже если CanConvertTo возвращает true.

например. «12» может быть преобразовано в целое число, но «тест» не может быть. Однако конвертер скажет, что он может преобразовать из строки в целое число.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...