Кастинг в штучной упаковке байт - PullRequest
6 голосов
/ 17 ноября 2011

Я пытаюсь написать метод расширения, который при заданном значении вернет

  • Само значение, если оно отличается от DBNull.Value
  • Значение по умолчанию для типа value

Да, это не самое ясное объяснение, может быть, какой-то код сделает то, что я пытаюсь сделать, очевидным.

public static T GetValueOrDefault<T>(this object value) {
    if (value == DBNull.Value)
        return default(T);
    else
        return (T)value;
}

Пока коробочный тип value совпадает с T, этот метод работает правильно.

Настоящее веселье проявляется, когда типы различаются, например, в штучной упаковке значение byte и T равно int.

Есть ли элегантный способ сделать эту работу?

Выполнение некоторой проверки типов вручную для первого приведения, например, object до byte, а затем от byte до T, конечно, не будет работать.

Редактировать

Предлагаемое решение должно работать и с перечислениями, а не только со "стандартными" типами.

Ответы [ 3 ]

4 голосов
/ 17 ноября 2011

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

int result = (int) row["NullableByteColumn"].GetValueOrDefault<byte>();

Я думаю, что это разумно, потому что код четко разделяет две различные концепции, которые здесь работают:

  • Считывание значения базы данных в правильный эквивалентный тип данных .NET.
  • Отображение типа уровня доступа к базе данных в требуемый тип уровня бизнес-логики.

Это разделение ответственности становится более важным, если требуемый тип данных является чем-то еще более удаленным из int и требует более сложного перевода, например, перечисление, строка или смещение дня от даты.

2 голосов
/ 17 ноября 2011
    public static T GetValueOrDefault<T>(this object value) {
        if (value == DBNull.Value) {
            return default(T);
        }
        else {
            if (typeof(T).IsEnum) value = Enum.ToObject(typeof(T), Convert.ToInt64(value));
            return (T)Convert.ChangeType(value, typeof(T));
        }
    }
0 голосов
/ 17 ноября 2011

Это работает для меня:

class Program
{
    static void Main(string[] args)
    {
        Byte myByte = 5;

        object myObject = (object)myByte;

        int myInt = myObject.GetValueOrDefault<Byte>();
        Console.WriteLine(myInt); // 5

        myObject = DBNull.Value;

        myInt = myObject.GetValueOrDefault<Byte>();
        Console.WriteLine(myInt); // 0

        Console.ReadKey(true);
    }
}

public static class ObjectExtension
{
    public static T GetValueOrDefault<T>(this object value)
    {
        if (value == DBNull.Value)
        {
            return default(T);
        }
        else
        {
            return (T)value;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...