C# 在C中正确处理异常和日志#
假设我有一个类Person,具有不同数据类型的不同属性,我的主方法中有以下代码:C# 在C中正确处理异常和日志#,c#,exception,logging,C#,Exception,Logging,假设我有一个类Person,具有不同数据类型的不同属性,我的主方法中有以下代码: Person p1 = new Person { Name = inputName, DateOfBirth = inputDOB, Height = height, Weight = weight, Passport = inputPassport }; 现在,假设高度的赋值引发了一个异常,例如InvalidCast
Person p1 = new Person
{
Name = inputName,
DateOfBirth = inputDOB,
Height = height,
Weight = weight,
Passport = inputPassport
};
现在,假设高度的赋值引发了一个异常,例如InvalidCastException,代码将停止执行,并且可能会记录一些东西,以防我有一个记录表。
问题是,从日志中,我无法确切地理解哪一行和赋值抛出了异常
是否有任何方法可以捕获异常,并能够记录(数据库中的某个位置)哪个赋值引发异常,以及在这种情况下针对哪种类型的强制转换(例如double to DateTime)
更新: 最后,我通过这样做解决了我的问题:
这是一个众所周知的问题。以下是一些与此相关的链接:
C#7.3(.net4.7.2)
和C#8(.netcore3.1)
测试了您的场景,问题仍然存在。因此,如果使用对象初始值设定项且其中一个初始值设定项值引发异常,则无法从堆栈跟踪中知道哪个初始值设定项值导致异常
解决方法
让我们考虑下一类<代码>人<代码>:
class Person
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public int Age { get; set; }
}
并假设使用下一个代码创建类Person
的实例:
// Return type of the methods getName(), getDateOfBirth() and getAge() is object.
// Each of this methods can return invalid value, for example, method getAge()
// can return string value causing InvalidCastException.
Person p = new Person
{
Name = (string) getName(),
DateOfBirth = (DateTime) getDateOfBirth(),
Age = (int) getAge()
};
如果某个初始值设定项值(例如,将方法getName()
的结果强制转换为string
数据类型)引发异常,我们将无法知道哪个初始值设定项值是异常的原因,因为堆栈跟踪中的行号将指向行Person p=new Person
要解决此问题,我们可以拒绝使用对象初始值设定项,而使用旧式对象初始化:
Person p = new Person();
p.Name = (string) getName();
p.DateOfBirth = (DateTime) getDateOfBirth();
p.Age = (int) getAge();
现在,如果发生异常,我们将能够知道发生异常的确切行号
在这里,我们必须在可读性(对象初始值设定项)和获取初始化期间异常原因的更准确信息之间进行选择
还有其他解决办法。例如,我们可以在对象初始值设定项中使用初始值设定项值之前检查它们:
结论 这是一个众所周知的问题。它仍然存在,尚未修复。我们可以通过拒绝使用对象初始值设定项和使用属性设定项(
p.Name=(string)getName()
)来解决这个问题。还可以使用另一种解决方法(例如,在使用对象初始值设定项之前检查初始值设定项值)
我们应该小心地使用对象初始值设定项。如果初始化值可以抛出异常,我们应该考虑使用属性设置器初始化对象(