Как можно проверить на “безопасные” преобразования между типами значения в.NET?

Назад к основам...

Для ссылочных типов можно сделать это:

        SomeType someObject = firstObject as SomeType;
        if (someObject == null)
        {
            // Handle the situation gracefully
        }
        else
        {
            // Do stuff
        }

Для типов значения мое понимание - то, что у нас есть неявные преобразования (никакая потеря данных), явные преобразования (необходимый, если существует риск потери данных), Convert класс ("обертка преобразования" я думаю) и также определенные для типа преобразования (например. double x = Double.Parse("2");), но я ничто не нашел подобным as оператор выше.

Так, мой вопрос: делает платформу, предоставляют некоторый метод/оператор/технику, чтобы сделать что-то вдоль этих строк:

        if (!Convert.CanConvert(someValue, someValueType))
        {
            // Beware! Data loss can occur
        }
        else
        {
            // No data loss here
        }

В противном случае может любой там предлагать, чтобы серьезный подход создал один такой CanConvert метод?

Большое спасибо!

РЕДАКТИРОВАНИЕ (1): user-case/problem следующие: Данный что-то, переданное потребителем кода (мой другой сам, но это не важно), (1) Проверяете, что что-то - число (достаточно легкий) и (2) Помещаете что-то в "самый маленький" числовой тип, где он подходит, не подвергаясь к потере данных.

Некоторый фон: природа того, что я пытаюсь сделать, является более математической, чем технический: я пытаюсь видеть, могу ли я соответствовать существующим числовым типам в своего рода алгебраическая иерархия Моноида формы => Группа => Кольцо => Поле (или упрощенная версия этого). При работе над этим, и не очень уверенный, как, "одна вещь привела к другому" и я имел необходимость для контакта с преобразованиями типов...

6
задан d.. 23 January 2010 в 19:53
поделиться

6 ответов

Как насчет метода Tryparse на различных типах значений?

int x;

if (int.TryParse(someType.ToString(), out x))
    return x;
3
ответ дан 10 December 2019 в 02:47
поделиться

Взгляните на Convert.ChangeType. Вы можете перехватить его в соответствии с вашими целями, хотя он будет медленным из-за бросания исключений и дублирующего преобразования.

1
ответ дан 10 December 2019 в 02:47
поделиться

Я думаю, что вы неправильно понимаете точку оператора в качестве оператора. Как оператор в качестве примерно эквивалентен следующему коду:

if (firstObject is SomeType)
  return (SomeType)firstObject;
else
  return null;

, так как больше проверки наследования. (Например, список реализует Ilist)

Типы значений не поддерживают наследство, а по причинам. Двойной и INT64 оба хранят номер 1 в совершенно разных манерах.

В основном то, что вы хотите, это метод, который определит вас, является ли преобразование числа безрежным или нет. Ну, я против "почему?". Хотя есть довольно несколько форматов, поддерживаемых CLR, правила преобразования обычно довольно просты. Например INT32 -> Double без потерь, и любая преобразование от «меньшей» на «больше» без потерь, такого как sbyte -> int64.

Другой вопрос, что бы ложь в вашем примере означает? Я бы очень мало сказал, например:

Convert.CanConvert(123456789.12345F, typeof(Byte))

того, что использование является ложным результатом? Вы подразумеваете для случаев, таких как INT32 -> Single, где некоторые данные будут потеряны, но в этом случае теряется тонна данных, так как «ближайшее» байтовое представление составляет 255.

Это из-за этих двух Проблемы, которые нет такого метода.

1
ответ дан 10 December 2019 в 02:47
поделиться

Как насчет метода Tryparse на различных типах значений?

int x;

if (int.TryParse(someType.ToString(), out x))
    return x;
-121--4321207-

как оператор основан на наследстве, а типы стоимости не наследуют. Возможно, вы могли бы написать CANConvert () , но он должен был бы работать с корпусом ValueTypes, и вы обычно хотите избежать бокса.

Итак, возможно: Да, желательно: Нет.

Может быть, вы можете добавить сценарий использования, где вы хотите использовать это, а затем мы можем порекомендовать альтернативы.

Re: Edit (1)

Я надеюсь, что вы знаете, что система численных типов является в основном исторический багаж и не следит за очень логическими правилами. Существует, например, нет такой вещи, как COLT расчета, они всегда преобразуются в INT, прежде чем делать что-либо.

Но, возможно, вы можете определить это поведение с точки зрения кольца и поля, эта алгебра была «долгое время прохождение» для меня.

1
ответ дан 10 December 2019 в 02:47
поделиться

Ключевое слово «AS» в основном безопасное снижение. Поскольку все типы значений запечатаны, их нельзя унаследовать.

Итак, ваш код будет:

if (firstObject is MyValueType)
{
   MyValueType obj = (MyValueType) firstObject;
}
else
{
}
1
ответ дан 10 December 2019 в 02:47
поделиться

Хенк в значительной степени на деньгах. Я хотел бы добавить кое-что в его ответ, если бы я хотел:

Преобразование типа ценности в .NET Framework работает с использованием интерфейса IConvertible. Класс Convert использует это практически для всех своих методов. Это сильно отличается от неявных/неявных операторов преобразования на C#, которые являются всего лишь еще одной формой синтаксического сахара.

Если вы напишете это:

public struct Duck
{
    public static implicit operator Goose(Duck d)
    {
        ...
    }
}

, то .NET Framework сам по себе не имеет ни малейшего представления о том, что это существует. Она излучается как op_implicit и это зависит от скомпилированного языка, чтобы понять, как его использовать. Не каждый язык MSIL на самом деле поддерживает их. Так что этот код работает:

Goose g1 = duck;

Этот код не работает:

Goose g1 = (Goose)Convert.ChangeType(duck, typeof(Goose));

Для реализации метода CanConvert, который знает о неявных/выраженных операторах преобразования, на самом деле нужно использовать Reflection для проверки отдельных методов op_, и я бы не рекомендовал это делать - на практике я вижу мало пользы от этого.

2
ответ дан 10 December 2019 в 02:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: