使用 TryParse 设置对象属性值

6

我目前正在重构代码,将Convert.To替换为TryParse。

我遇到了以下代码片段,它正在创建并将属性分配给一个对象。

List<Person> list = new List<Person>();

foreach (DataRow row in dt.Rows)
{
     var p = new Person{ RecordID = Convert.ToInt32(row["ContactID"]) };

     list.Add(p);
}

我想到了一个替代方案:
var p = new Person { RecordID = Int32.TryParse(row["ContactID"].ToString(), out RecordID) ? RecordID : RecordID };

你有什么想法、意见或者替代方案吗?


不太易读,但如果它能用就行…… - DilbertDave
我同意迪尔伯特的观点。我认为单行代码更难阅读,而且在编辑或调试时会很痛苦。TryParse听起来像是一种改进。 - DOK
由于ContactID是数据库中的主键,将其转换为Int32将始终成功。尝试使用TryParse会误导代码维护者,因为它暗示转换有时可能会失败,但实际上并非如此。我建议仍然使用Convert.ToInt32。 - Bradley Grainger
我同意Bradley Grainger的观点,这里使用TryParse是错误的。 - xsl
为什么要替换它? - Caltor
4个回答

11

编写一个扩展方法。

public static Int32? ParseInt32(this string str) {
    Int32 k;
    if(Int32.TryParse(str, out k))
        return k;
    return null;
}

如果返回0而不是null,这样与原始功能一致,你不想要吗? - Godless667
在这种情况下,由于无法解析(返回null)与解析为0(返回0)之间应该有所区别。 - xsl
@Godless 不行。你需要一个通用的东西,这样就可以重复使用。如果需要默认为0,则应使用(“1234”。TryParseInt32()?? 0)。 - yfeldblum
这也不易读。人们会期望一个名为“TryParseInt32”的方法返回布尔值。 - Serhat Ozgel
重命名扩展方法。 - yfeldblum

3

我建议使用另一种实现方式 TryParse,它返回一个可空的int类型:

public static int? TryParseInt32(string x)
{
    int value;
    return int.TryParse(x, out value) ? value : (int?) null;
}

然后,你可以写下以下内容:
var p = new Person { RecordID = Helpers.TryParseInt32(row["ContactID"].ToString()) ?? 0 };

(如果您想使用不同的默认值,也可以-无论哪种方式,它都将在您的代码中可见。)

0
我建议将TryParse部分与初始化器分开。这样会更易读。
int recordId;
Int32.TryParse(row["ContactID"].ToString(), out recordID)

foreach (DataRow row in dt.Rows)
{
     var p = new Person{ RecordID = recordId };
     list.Add(p);
}

我也考虑过这个(不过你需要将那部分放在foreach块内)。我试图编写更简洁的代码。特别是当你在创建对象时设置多个属性时。 - Godless667
那你为什么不为 Person 创建一个构造函数,该构造函数获取 DataRow 并在其中执行你想要的操作呢? - Ali Ersöz
1
一个Person类为什么需要通过ODBC和ADO.NET理解关系型数据库持久化的语义呢?它需要理解如何从二进制网络流构建自身吗?从CSV文件中构建自身吗?等等? - yfeldblum
@Justice - 当然,你是对的。我完全没有话可说 :) - Ali Ersöz

0
private static void TryToDecimal(string str, Action<decimal> action)
{
        if (decimal.TryParse(str, out decimal ret))
        {
            action(ret);
        }
        else
        {
            //do something you want
        }
}

TryToDecimal(strList[5], (x) => { st.LastTradePrice = x; });
TryToDecimal(strList[3], (x) => { st.LastClosedPrice = x; });
TryToDecimal(strList[6], (x) => { st.TopPrice = x; });
TryToDecimal(strList[7], (x) => { st.BottomPrice = x; });
TryToDecimal(strList[10], (x) => { st.PriceChange = x; });

他的问题标题是“使用TryParse设置对象属性值”。我的回答是使用TryToDecimal来设置对象属性,例如LastTradePrice、LastClosedPrice、TopPrice、BottomPrice和PriceChange。 - alanthinker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接