Я обновляю существующее приложение, которое реализовало доморощенный класс Констант в его бизнесе и объектах datalayer.
Я хочу заменить это типами Nullable и покончить с классом констант, который похож на это, но со всеми не допускающими NULL-значения типами данных:
class Constants
{
public static int nullInt
{
get { return int.MinValue; }
}
}
Эти значения констант используются в качестве значений по умолчанию почти на всех свойствах объектов как это:
private decimal _unitPrice = Constants.nullInt;
public decimal UnitPrice
{
get { return _unitPrice; }
set { _unitPrice = (value == null) ? Constants.nullInt : value; }
}
Это вызывает некоторый беспорядок при сохранении свойств объектов к дб как все десятичное число, и ints должны быть проверены на psudo нулевые значения, или иначе Вы сохраняете вещи как интервал. MinValue к дб.
private void Save()
{
//Datalayer calls and other props omitted
SqlParameter sqlParm = new SqlParameter();
sqlParm.Value = (this.UnitPrice == Constants.nullInt) ? DBNull.Value : (object)this.UnitPrice;
}
Хорошо поэтому теперь вопрос.. Я хочу изменить вещи вокруг использования типов значения Nullable как в моем примере ниже, будет изменение в свойстве от десятичного числа до десятичного числа? влияйте на какой-либо код, это реализует эти объекты?
public decimal? UnitPrice { get; set; }
private void Save()
{
//Datalayer calls and other props omitted
SqlParameter sqlParm = new SqlParameter();
sqlParm.Value = this.UnitPrice ?? DBNull.Value;
}
Править: Спасибо за двойную проверку моего осуществляла рефакторинг, и да пустая проверка на съемочной площадке свойства в исходном коде была бы избыточна. Я все еще хочу знать, мог ли код, который реализует этот объект, иметь какие-либо проблемы от изменения типа к десятичному числу? от десятичного числа
public decimal? UnitPrice { get; set; }
private void Save()
{
//Datalayer calls and other props omitted
SqlParameter sqlParm = new SqlParameter();
sqlParm.Value = this.UnitPrice ?? DBNull.Value;
}
Я нахожу это абсолютно нормальным. Вот как это должно работать.
Я немного неясен в том, что касается реализации описанного выше метода набора свойств, так как десятичная дробь никогда не может быть нулевой, поэтому данный тест, на мой взгляд, излишний. Я включаю пример кода, который можно выкинуть в консольное приложение, которое должно все прояснить.
У вас будет очень мало рефакторинга вашего кода из-за перехода на нулевые типы данных. Это будет хорошим шагом с вашей стороны в очистке вашего кода и предотвращении потенциальных ловушек вашей текущей реализации.
Если ничего больше, то прирост производительности, который вы получите, скорее всего, сделает ваши усилия стоящими того. Ничто не будет полностью само собой разумеющимся, так сказать, plug-n-play, но если вы посмотрите на нижеприведенный код, то увидите, что в предоставленных вами сценариях влияние очень незначительное.
using System;
using System.Data.SqlClient;
namespace NullableTypes
{
class Program
{
static class Constants
{
public static decimal NullDecimal
{
get { return decimal.MinValue; }
}
}
public class ProductTheOldWay
{
public string Name { get; set; }
public decimal UnitPrice { get; set; }
public ProductTheOldWay()
{
Name = string.Empty;
UnitPrice = Constants.NullDecimal;
}
public override string ToString()
{
return "Product: " + Name + " Price: " +
((UnitPrice == Constants.NullDecimal)
? "Out of stock"
: UnitPrice.ToString());
}
public void Save()
{
//Datalayer calls and other props omitted
var sqlParm = new SqlParameter
{
Value = (UnitPrice == Constants.NullDecimal)
? DBNull.Value
: (object)UnitPrice
};
//save to the database...
Console.WriteLine("Value written to the database: " + sqlParm.Value);
}
}
public class ProductTheNewWay
{
public string Name { get; set; }
public decimal? UnitPrice { get; set; }
public ProductTheNewWay()
{
Name = string.Empty;
}
public override string ToString()
{
return "Product: " + Name + " Price: " +
((UnitPrice.HasValue)
? UnitPrice.ToString()
: "Out of stock");
}
public void Save()
{
//Datalayer calls and other props omitted
var sqlParm = new SqlParameter
{
Value = UnitPrice
};
//save to the database...
Console.WriteLine("Value written to the database: " + sqlParm.Value);
}
}
static void Main()
{
var oldProduct1 = new ProductTheOldWay
{
Name = "Widget",
UnitPrice = 5.99M
};
var oldProduct2 = new ProductTheOldWay
{
Name = "Rare Widget",
UnitPrice = Constants.NullDecimal // out of stock
};
Console.WriteLine(oldProduct1);
Console.WriteLine(oldProduct2);
Console.WriteLine("Saving...");
oldProduct1.Save();
oldProduct2.Save();
Console.ReadLine();
var newProduct1 = new ProductTheNewWay
{
Name = "Widget",
UnitPrice = 5.99M
};
var newProduct2 = new ProductTheNewWay
{
Name = "Rare Widget"
/* UnitPrice = null by default */
};
Console.WriteLine(newProduct1);
Console.WriteLine(newProduct2);
Console.WriteLine("Saving...");
newProduct1.Save();
newProduct2.Save();
Console.ReadLine();
// as a further example of the new property usage..
if (newProduct1.UnitPrice > 5)
Console.WriteLine(newProduct1);
Console.WriteLine("Using nullable types is a great way to simplify code...");
Console.ReadLine();
}
}
}
Product: Widget Price: 5.99
Product: Rare Widget Price: Out of stock
Saving...
Value written to the database: 5.99
Value written to the database:
Product: Widget Price: 5.99
Product: Rare Widget Price: Out of stock
Saving...
Value written to the database: 5.99
Value written to the database:
Product: Widget Price: 5.99
Использование нулевых типов данных - отличный способ упростить код...
Дайте мне знать, если есть более конкретные детали реализации, которые касаются создания переключателя.