如何用默认的“base”值替换空值或null值?

时间:2013-11-25 19:24:25

标签: c# null double default-value argumentexception

使用以下代码:

foreach (JObject obj in arr)
{
    id = (string)obj["Id"];
    packSize = (Int16)obj["PackSize"];
    var description = (string)obj["Description"];
    var deptSubdept = (Double)obj["DeptDotSubdept"];
    var unitCost = (Double)obj["Unit_Cost"];
    var unitList = (Double)obj["Unit_List"];
    var UPC_Code = (string)obj["UPC_code"];
    var UPC_packSize = (Int16)obj["UPC_pack_size"];
    var CRVId = (Int32)obj["CRV_Id"];

inventoryItems.Add(new WebAPIClientUtils.InventoryItem
{
    Id = id,
    PackSize = packSize,
    Description = description,
    DeptDotSubdept = deptSubdept,
    Unit_Cost = unitCost,
    Unit_List = unitList,
    UPC_code = UPC_Code,
    UPC_pack_size = UPC_packSize,
    CRV_Id = CRVId
});

...我收到了,“ System.ArgumentException:输入字符串格式不正确。无法在成本列中存储<>。预期类型为Double .---> System.FormatException ... 的“

注意:“Cost”是以这种方式定义的本地表中列的名称:

// Create temp table that mirrors InventoryItems as a staging area for the data to be bulk copied
var dt = new DataTable();
dt.Columns.Add(new DataColumn("Id", typeof(string)));
. . .
dt.Columns.Add(new DataColumn("Cost", typeof(double)));
. . .

因此,当检索到的数据具有这些虚假/空值时,如何检查并使用诸如0.00的值用于双精度,0用于int,string.empty用于String,& c?

要知道发生这种情况的时间,我在这一行放了一个条件断点:

var unitCost = (Double)obj["Unit_Cost"];

...在Breakpoint Condition对话框中输入以下内容:

unitCost.ToString() == ""

......但它永远不会到达。我还尝试将“ unitCost == null ”设置为条件断点,并使用相同的[非]结果。

更新

有了这个:

id = (string)obj["Id"] ?? string.Empty;
packSize = (Int16)obj["PackSize"] ?? 0;
var description = (string)obj["Description"] ?? string.Empty;
var deptSubdept = (Double)obj["DeptDotSubdept"] ?? 0.0;
var unitCost = (Double)obj["Unit_Cost"] ?? 0.0;
var unitList = (Double)obj["Unit_List"] ?? 0.0;
var UPC_Code = (string)obj["UPC_code"] ?? string.Empty;
var UPC_packSize = (Int16)obj["UPC_pack_size"] ?? 0;
var CRVId = (Int32)obj["CRV_Id"] ?? 0;

......我明白了:

运营商'??'不能应用于'short'和'int'类型的操作数 接线员'??'不能应用于'double'和'double'类型的操作数 接线员'??'不能应用于'int'和'int'

类型的操作数

更新2

我试过了:

double unitCost;
if (obj["Unit_Cost"] != DBNull.Value)
{
    unitCost = (Double) obj["Unit_Cost"];
}
else
{
    unitCost = 0.0;
}

...并获取,“运算符'!='无法应用于'Newtonsoft.Json.Linq.JToken'和'System.DBNull'类型的操作数”

更新3

将条件赋值的初始部分包含在这样的parens中:

var UPC_Code = ((string)obj["UPC_code"]) ?? string.Empty;

...仅适用于字符串;我仍然得到其他数据类型的错误消息(int和double)。

更新4

此代码中发生了运行时异常:

dt.Rows.Add(invItem.Id, invItem.PackSize, invItem.Description, invItem.DeptDotSubdept,  
    invItem.Unit_Cost, invItem.Unit_List, invItem.UPC_code, invItem.UPC_pack_size, 
    invItem.CRV_Id);

...所以我试过了:

int packSize = 1;
double unitCost = 0.0;
double unitList = 0.0;

if (invItem.PackSize != null)
{
    packSize = invItem.PackSize;
}
if (invItem.Unit_Cost != null)
{
    unitCost = invItem.Unit_Cost;
}
if (invItem.Unit_List != null)
{
    unitList = invItem.Unit_List;
}

dt.Rows.Add(invItem.Id, packSize, invItem.Description, 
    invItem.DeptDotSubdept, unitCost, unitList, invItem.UPC_code, 
    invItem.UPC_pack_size, invItem.CRV_Id);

...但它仍然失败,并且“!= null”行在编辑器中有蓝色波浪形的情况。

更新5

至于SLaks的建议,我试过了:

if (obj["Unit_Cost"] == DBNull.Value)
{
    unitCost = 0.0;
}
else
{
    unitCost = (Double)obj["Unit_Cost"];
}

...但是得到,“运算符'=='不能应用于'Newtonsoft.Json.Linq.JToken'和'System.DBNull'类型的操作数”

我对此有同感:

if ((Double)obj["Unit_Cost"] == DBNull.Value)

....而且:

if (((Double)obj["Unit_Cost"]) == DBNull.Value)

更新6

我看到当失败时,unitCost的值不为null,而是0.所以,我设置了一个断点,在那里分配了该值:

unitCost == 0

...但是即使值为0.0(这很好),断点也会被击中。我认为即使0也没关系,但......它失败了,所以价值明显错误。

6 个答案:

答案 0 :(得分:1)

您看到的是DBNull.Value,它会覆盖ToString()以返回""

检查

if (obj["Unit_Cost"] == DBNull.Value)

如果objDataRow,您也可以致电obj.IsNull("Unit_Cost")

答案 1 :(得分:1)

您可以使用默认值  var def = (Double)(obj["Unit_Cost"] ?? default(Double));

答案 2 :(得分:1)

如果您使用DeserializeObject代替JObject,则可以使用DefaultValueAttributeDefaultValueHandling轻松完成此操作:

void Main()
{
    var item = JsonConvert.DeserializeObject<InventoryItem>(@"{""Id"": 1}",
         new JsonSerializerSettings {
                DefaultValueHandling = DefaultValueHandling.Populate });
    // item.PackSize == 1
}
public class InventoryItem
{
    public string Id { get; set; }
    [DefaultValue(1)]
    public Int16 PackSize { get; set; }
    [DefaultValue("")]
    public string Description { get; set; }
    public Double DeptDotSubdept { get; set; }
}

答案 3 :(得分:1)

试试这个

Double dbl;
Int16 int16;
Int32 int32;

    foreach (JObject obj in arr)
    {
        id = (string)obj["Id"];
        packSize = Int16.TryParse(obj["PackSize"].ToString(), out int16) ? (Int16)obj["PackSize"]:0;
        var description = (string)obj["Description"];
        var deptSubdept = Double.TryParse(obj["DeptDotSubdept"].ToString(), out dbl) ? (Double)obj["DeptDotSubdept"] : 0.00;
        var unitCost = Double.TryParse(obj["Unit_Cost"].ToString, out dbl) ? (Double)obj["Unit_Cost"] : 0.00;
        var unitList = Double.TryParse(obj["Unit_List"].ToString(), out dbl) ? (Double)obj["Unit_List"] : 0.00;
        var UPC_Code = (string)obj["UPC_code"];
        var UPC_packSize = Int16.TryParse(obj["UPC_pack_size"].ToString(), out int16) ? (Int16)obj["UPC_pack_size"] : 0;
        var CRVId = Int32.TryParse(obj["CRV_Id"].ToString(), out int32) ? (Int32)obj["CRV_Id"] : 0;

    inventoryItems.Add(new WebAPIClientUtils.InventoryItem
    {
        Id = id,
        PackSize = packSize,
        Description = description,
        DeptDotSubdept = deptSubdept,
        Unit_Cost = unitCost,
        Unit_List = unitList,
        UPC_code = UPC_Code,
        UPC_pack_size = UPC_packSize,
        CRV_Id = CRVId
    })

答案 4 :(得分:1)

尝试使用as运算符转换为可空类型并使用Nullable(T).GetValueOrDefault

foreach (JObject obj in arr)
{
    var id = obj["Id"] as string;
    var packSize = obj["PackSize"] as short?;
    var description = obj["Description"] as string;
    var deptSubdept = obj["DeptDotSubdept"] as double?;
    var unitCost = obj["Unit_Cost"] as decimal?;
    var unitList = obj["Unit_List"] as decimal?;
    var UPC_Code = obj["UPC_code"] as string;
    var UPC_packSize = obj["UPC_pack_size"] as short?;
    var CRVId = obj["CRV_Id"] as int?;

    inventoryItems.Add(new WebAPIClientUtils.InventoryItem
    {
        Id = id ?? string.Empty,
        PackSize = packSize.GetValueOrDefault(),
        Description = description ?? string.Empty,
        DeptDotSubdept = deptSubdept.GetValueOrDefault(),
        Unit_Cost = unitCost.GetValueOrDefault(),
        Unit_List = unitList.GetValueOrDefault(),
        UPC_code = UPC_Code ?? string.Empty,
        UPC_pack_size = UPC_packSize.GetValueOrDefault(),
        CRV_Id = CRVId.GetValueOrDefault()
    });
}

还可以使用decimal作为货币。

答案 5 :(得分:1)

根据this answer以及有关您的类型的最新信息,尝试执行以下操作:

id = obj.Value<string>("Id") ?? "";
packSize = obj.Value<short?>("PackSize") ?? (short)0;
var description = obj.Value<string>("Description") ?? "";
var deptSubdept = obj.Value<double?>("DeptDotSubdept") ?? 0.0;
var unitCost = obj.Value<double?>("Unit_Cost") ?? 0.0;
...
var crvId = obj.Value<int>("CRV_Id") ?? 0;