Назад к основам...
Для ссылочных типов можно сделать это:
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) Помещаете что-то в "самый маленький" числовой тип, где он подходит, не подвергаясь к потере данных.
Некоторый фон: природа того, что я пытаюсь сделать, является более математической, чем технический: я пытаюсь видеть, могу ли я соответствовать существующим числовым типам в своего рода алгебраическая иерархия Моноида формы => Группа => Кольцо => Поле (или упрощенная версия этого). При работе над этим, и не очень уверенный, как, "одна вещь привела к другому" и я имел необходимость для контакта с преобразованиями типов...
Как насчет метода Tryparse на различных типах значений?
int x;
if (int.TryParse(someType.ToString(), out x))
return x;
Взгляните на Convert.ChangeType
. Вы можете перехватить его в соответствии с вашими целями, хотя он будет медленным из-за бросания исключений и дублирующего преобразования.
Я думаю, что вы неправильно понимаете точку оператора в качестве оператора. Как оператор в качестве примерно эквивалентен следующему коду:
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.
Это из-за этих двух Проблемы, которые нет такого метода.
Как насчет метода Tryparse на различных типах значений?
int x;
if (int.TryParse(someType.ToString(), out x))
return x;
-121--4321207- как оператор
основан на наследстве, а типы стоимости не наследуют. Возможно, вы могли бы написать CANConvert ()
, но он должен был бы работать с корпусом ValueTypes, и вы обычно хотите избежать бокса.
Итак, возможно: Да, желательно: Нет.
Может быть, вы можете добавить сценарий использования, где вы хотите использовать это, а затем мы можем порекомендовать альтернативы.
Re: Edit (1)
Я надеюсь, что вы знаете, что система численных типов является в основном исторический багаж и не следит за очень логическими правилами. Существует, например, нет такой вещи, как COLT
расчета, они всегда преобразуются в INT, прежде чем делать что-либо.
Но, возможно, вы можете определить это поведение с точки зрения кольца и поля, эта алгебра была «долгое время прохождение» для меня.
Ключевое слово «AS» в основном безопасное снижение. Поскольку все типы значений запечатаны, их нельзя унаследовать.
Итак, ваш код будет:
if (firstObject is MyValueType)
{
MyValueType obj = (MyValueType) firstObject;
}
else
{
}
Хенк в значительной степени на деньгах. Я хотел бы добавить кое-что в его ответ, если бы я хотел:
Преобразование типа ценности в .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_
, и я бы не рекомендовал это делать - на практике я вижу мало пользы от этого.