我试图防止System.NullReferenceException。完全合格的属性名称
我有一个公司,其中有员工的集合。每个员工都有一系列技能。
SelectedEmployee指向Employee集合中当前选定的元素。
SelectedSkill指向技能集合中当前选定的元素。
我有一个ListView的ItemSource绑定到Skills集合; ListView的SelectedItem绑定到SelectedSkill。
当技能被删除时我希望ListView滚动到最后一个元素。
private void DeleteSelectedSkillFromSelectedEmployee()
{
Company.SelectedEmployee.Skills.Remove(Company.SelectedEmployee.SelectedSkill);
EmployeeSkillsListView.ScrollIntoView(Company.SelectedEmployee.Skills.Last());
}
如果没有选择员工,则SelectedEmployee将为空。这将在方法内部执行任何操作时导致System.NullReferenceException。
注:我已经使用扩展方法来替换.Last(),因此它不会在空集合上出错。
为了解决这个问题我使用一个实用程序方法:
public static class Utils
{
public static bool PropertyExists(Object obj, String name)
{
foreach (String part in name.Split('.'))
{
if (obj == null) { return false; }
Type type = obj.GetType();
System.Reflection.PropertyInfo info = type.GetProperty(part);
if (info == null) { return false; }
obj = info.GetValue(obj, null);
}
return obj != null;
}
}
所以它现在看起来是这样的:上面
private void DeleteSelectedSkillFromSelectedEmployee()
{
if(Utils.PropertyExists(Company, "SelectedEmployee.SelectedSkill"))
{
Company.SelectedEmployee.Skills.Remove(Company.SelectedEmployee.SelectedSkill);
EmployeeSkillsListView.ScrollIntoView(Company.SelectedEmployee.Skills.Last());
}
}
,一切工作正常。这不是确切的场景或代码,所以不要担心纠正以上任何内容(只是假设它工作正常)。这只是我真正感兴趣的问题。
(想象一下,这是SelectedEmployee和SelectedSkill不为null)
有没有得到一个属性的完全合格的名称的方法吗? 所以,我可以这样做:
if(Utils.PropertyExists(Company, GetFullyQualifiedName(Company.SelectedEmployee.SelectedSkill)))
凡GetFullyQualifiedName(Object)返回 “Company.SelectedEmployee.SelectedSkill”。
问题的第二部分:想象一下SelectedEmployee为null:是否有任何方法允许将NullReference传递给方法? 我99.9%肯定答案是否定的:)
你为什么用反射烦心事字符串?为什么不简单检查'Company.SelectedEmployee!= null'? – Jamiec
想象一下,一个属性有多少个零件;其中任何一个都可能为空。 A.B.C.D.E.F.G.H.SelectedSkill。我不想有一个巨大的If语句来检查每一个。 – James