由PropertyInfo.setvalue抛出的trap setter异常
本文关键字:trap setter 异常 PropertyInfo setvalue | 更新日期: 2023-09-27 18:06:37
我有一种情况,在classA的PropertyInfo上放置SetValue周围的try-catch不会捕获由classA属性的setter抛出的异常。我如何捕捉这个案例?在下面的例子:
public class classA
{
private string _ID;
public string ID
{
get { return _ID; }
set
{
if (_ID == null) _ID = value;
else throw new InvalidOperationException();
}
}
}
public class classB
{
public void DoMagic()
{
classA MyA = new classA();
PropertyInfo pi = GetPropertyInfoForProperty(typeof(classA), "ID");
try
{
pi.SetValue(MyA, "This works fine", null);
}
catch { }
///MyA.ID = "The first time you set it everything is cool.";
try
{
MyA.ID = "This throws a handled exception.";
}
catch { }
try
{
pi.SetValue(MyA, "This Throws and Unhandled Exception", null);
}
catch { }
}
private PropertyInfo GetPropertyInfoForProperty(Type type, string p)
{
foreach (var pi in type.GetProperties())
if (pi.Name == p)
return pi;
return null;
}
}
在审查代码后,我认为问题是classA
类的ID setter中的逻辑错误。当前代码是:
public class classA
{
private string _ID;
public string ID
{
get { return _ID; }
set
{
if (_ID == null) _ID = value;
else throw new InvalidOperationException();
}
}
}
当ID接收到null
以外的值时,上面的将总是抛出InvalidOperationException
。如果你第一次设置它,它总是有效的,但不是以后的时间。我打算建议在你的setter中重新安排if
语句,但后来我意识到,也许你的意图是使ID
属性只能设置一次,如下所示,但是当你第一次尝试设置它时,它会抛出同样的异常,所以这行不通。
public class classA
{
private string _ID;
public string ID
{
get { return _ID; }
set
{
// This will always throw an exception
if (_ID == null)
{
// Is this what you intended?
// That is, throw an InvalidOperationException if a null value is supplied?
throw new InvalidOperationException();
}
_ID = value;
}
}
}
话虽如此,我仍然不清楚为什么ID应该只设置一次,假设我的理解是正确的,但您可以尝试修改您的逻辑,以便通过构造函数设置ID并使ID setter private
。不幸的是,这将迫使您修改您打算执行的其余代码。没有太多信息,这是我最好的答案。请注意,按照惯例,我将抛出一个ArgumentException
,但您也可以抛出一个ArgumentNullException
。我选择前者是因为我使用了String.IsNullOrWhiteSpace()
方法。
public class classA
{
public string ID { get; private set; }
public classA(string id)
{
if (String.IsNullOrWhiteSpace(id))
{
throw ArgumentException("id");
}
ID = id;
}
}