Вопрос
Во-первых, два примера:
// This works
int foo = 43;
long lFoo = foo;
// This doesn't
object foo = (int)43;
long? nullFoo = foo as long?; // returns null
long lFoo = (long)foo; // throws InvalidCastException
if (foo.GetType() == typeof(int))
Console.WriteLine("But foo is an int..."); // This gets written out
Теперь, я предполагаю, что второе не работает из-за бокса.Целью этого кода является реализация IComparable
.Мне нужен какой-то способ принудительно преобразовать объект либо в long, либо в ulong, в зависимости от обстоятельств, или, если это ни то, ни другое, чем выдать ошибку.Я не хочу реализовывать проверки для каждого базового числового типа (byte, int, long, ubyte, ...) Я бы предпочел просто перехватить их в самом большом числовом типе и разобраться с этим таким образом.Мысли всех присутствующих здесь умных людей?Как я могу распаковать объект, предпочтительно избегая отражения, но я полагаю, что это единственный способ?..Или я должен просто не внедрять непатентованную версию IComparable
?
Редактировать:
Кажется, это работает, но выглядит как ужасный способ обойти проблему.Это только из-за меня?
long lFoo = long.Parse(foo.ToString());
Решение
object foo = (int) 43;
long lFoo = ((IConvertible) foo).ToInt64(null);
Другие советы
Когда вы приводите к типу значения, вы действительно принудительно выполняете операцию unbox IL, которая требует, чтобы тип, к которому вы приводите, соответствовал именно так значение в штучной упаковке;нет никаких преобразований, неявных или явных, которые могли бы произойти одновременно.
Обычно это означает, что вам либо нужно выполнить переключение с использованием кода типа (или if / else при использовании типов), либо, в вашем случае, выполнить проверку на null с последующим преобразованием.ToInt64(), который должен справиться с этим правильно.
Дело не только в вас, однако tryparse не вызывает исключения.
object foo = (int)43;
long outVal;
if(long.TryParse(foo.ToString(),out outVal))
{
//take action with correct value of long
}
else
{
//maybe passed you another type of object
}