我正在升级已在其业务和数据层对象中实现了Home-brew Constants类的现有应用程序。
我想用Nullable类型替换它,并使用常量类替换它,看起来像这样,但是所有非可空数据类型都是:
class Constants
{
public static int nullInt
{
get { return int.MinValue; }
}
}
这些常量vaules几乎用作所有对象属性的默认值:
private decimal _unitPrice = Constants.nullInt;
public decimal UnitPrice
{
get { return _unitPrice; }
set { _unitPrice = (value == null) ? Constants.nullInt : value; }
}
这会导致将对象属性保存到Db时出现一些混淆,因为必须检查所有小数和整数的psudo null值,否则就会将int.MinValue等内容保存到Db中。
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;
}
编辑:感谢我对重构的仔细检查,是的,对原始代码中属性SET的空检查将是多余的。我仍然想知道实现此对象的代码是否可以从类型更改到十进制? 十进制
的任何问题答案 0 :(得分:5)
public decimal? UnitPrice { get; set; }
private void Save()
{
//Datalayer calls and other props omitted
SqlParameter sqlParm = new SqlParameter();
sqlParm.Value = this.UnitPrice ?? DBNull.Value;
}
我觉得这绝对没问题。这就是它的工作方式。
答案 1 :(得分:0)
我对上面的属性集方法的实现有点不清楚,因为小数永远不能为null,所以我认为这个测试是多余的。我将包含一些示例代码,这些代码可以放入一个应该为您清理的控制台应用程序中。
由于切换到可以为空的数据类型,您将体验到很少的代码重构。这将是您清理代码并避免当前实施的潜在缺陷的一个很好的举措。
如果不出意外,您将获得的性能提升可能会让您的努力值得。没有什么可以完全即插即用,但是如果你看下面的代码,你会发现在你提供的场景中影响很小。
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
使用可空数据类型是简化代码的好方法......
如果有更多具体的实施细节与您进行转换,请与我们联系。