В настоящее время я занимаюсь рефакторингом кода, чтобы заменить 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 };
Есть мысли, мнения, альтернативы тому, что я сделал?
Я согласен с Дилбертом. Я думаю, что однострочник сложнее читать, и было бы больно пытаться редактировать или выполнять отладку. TryParse действительно кажется улучшением.
Поскольку ContactID является первичным ключом в базе данных, преобразование в Int32 всегда будет успешным. Использование TryParse вводит в заблуждение разработчика кода, так как подразумевает, что преобразование может иногда завершаться ошибкой, что не так. Я бы придерживался Convert.ToInt32.
Я согласен с Брэдли Грейнджером, здесь неправильно использовать TryParse.





Напишите метод расширения.
public static Int32? ParseInt32(this string str) {
Int32 k;
if (Int32.TryParse(str, out k))
return k;
return null;
}
Разве вы не хотели бы, чтобы он возвращал 0 вместо null, если false, чтобы соответствовать исходной функциональности?
В этом случае, потому что должна быть разница между неудачным синтаксическим анализом (возвращается null) и синтаксическим анализом 0 (возвращается 0).
@Godless Нет. Вам нужно что-то общее, которое можно использовать повторно. Если вам нужно установить значение по умолчанию на 0, вы должны использовать ("1234" .TryParseInt32 () ?? 0).
Это тоже не читается. Можно было бы ожидать, что метод с именем "TryParseInt32" вернет bool.
Переименовал метод расширения.
Я бы использовал альтернативную реализацию 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 };
(Или используйте другое значение по умолчанию, если хотите - в любом случае это будет видно в вашем коде.)
Я предлагаю отделить часть 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). Я пытался использовать более сжатый код. Особенно, если вы устанавливаете несколько свойств при создании объекта.
Так почему бы вам не создать конструктор для Person, который получает DataRow и делать в нем то, что вы хотите?
Зачем же классу Person понимать семантику персистентности реляционной базы данных через ODBC и ADO.NET? Должен ли он понимать, как построить себя из двоичного сетевого потока? Из файлов CSV? так далее?
@Justice - Конечно, вы правы. Мне совершенно нечего сказать :)
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.
Не так читабельно, но если работает ...