完全限定 属性 名称
Fully-qualified property name
我正在努力阻止 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());
}
如果未选择 Employee,则 SelectedEmployee 将为空。这将在方法内部执行任何操作时导致 System.NullReferenceException。
注意:我使用了扩展方法来替换 .Last(),因此它不会在空集合上出错。
为了解决这个问题,我使用了一个 Util 方法:
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 不为空)
有没有办法获得 属性 的完全限定名称?
所以我可以做类似的事情:
if(Utils.PropertyExists(Company, GetFullyQualifiedName(Company.SelectedEmployee.SelectedSkill)))
Where GetFullyQualifiedName(Object) returns "Company.SelectedEmployee.SelectedSkill".
问题的第二部分:假设 SelectedEmployee 为空:是否有任何方法允许将 NullReference 传递给方法?
我 99.9% 肯定答案是否定的:)
我不明白。为什么不只是:
private void DeleteSelectedSkillFromSelectedEmployee()
{
if(Company != null &&
Company.SelectedEmployee != null &&
Company.SelectedEmployee.Skills != null)
{
Company.SelectedEmployee.Skills.Remove(Company.SelectedEmployee.SelectedSkill);
EmployeeSkillsListView.ScrollIntoView(Company.SelectedEmployee.Skills.Last());
}
}
或者在 C#6 中
if(Company?.SelectedEmployee?.Skills != null)
{
...
}
如果您仍想使用那个 GetFullyQualifiedName
方法,您可以使用的最接近的方法可能是(不检查错误,这只是一个快速的 hack):
public static string GetPathOfProperty<T>(Expression<Func<T>> property)
{
string resultingString = string.Empty;
var p = property.Body as MemberExpression;
while (p != null)
{
resultingString = p.Member.Name + (resultingString != string.Empty ? "." : "") + resultingString;
p = p.Expression as MemberExpression;
}
return resultingString;
}
然后像这样使用它:
GetPathOfProperty(() => Foo.Bar.Baz.SomeProperty );
这将 return 一个包含 "Foo.Bar.Baz.SomeProperty"
的字符串
我正在努力阻止 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());
}
如果未选择 Employee,则 SelectedEmployee 将为空。这将在方法内部执行任何操作时导致 System.NullReferenceException。
注意:我使用了扩展方法来替换 .Last(),因此它不会在空集合上出错。
为了解决这个问题,我使用了一个 Util 方法:
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 不为空)
有没有办法获得 属性 的完全限定名称? 所以我可以做类似的事情:
if(Utils.PropertyExists(Company, GetFullyQualifiedName(Company.SelectedEmployee.SelectedSkill)))
Where GetFullyQualifiedName(Object) returns "Company.SelectedEmployee.SelectedSkill".
问题的第二部分:假设 SelectedEmployee 为空:是否有任何方法允许将 NullReference 传递给方法? 我 99.9% 肯定答案是否定的:)
我不明白。为什么不只是:
private void DeleteSelectedSkillFromSelectedEmployee()
{
if(Company != null &&
Company.SelectedEmployee != null &&
Company.SelectedEmployee.Skills != null)
{
Company.SelectedEmployee.Skills.Remove(Company.SelectedEmployee.SelectedSkill);
EmployeeSkillsListView.ScrollIntoView(Company.SelectedEmployee.Skills.Last());
}
}
或者在 C#6 中
if(Company?.SelectedEmployee?.Skills != null)
{
...
}
如果您仍想使用那个 GetFullyQualifiedName
方法,您可以使用的最接近的方法可能是(不检查错误,这只是一个快速的 hack):
public static string GetPathOfProperty<T>(Expression<Func<T>> property)
{
string resultingString = string.Empty;
var p = property.Body as MemberExpression;
while (p != null)
{
resultingString = p.Member.Name + (resultingString != string.Empty ? "." : "") + resultingString;
p = p.Expression as MemberExpression;
}
return resultingString;
}
然后像这样使用它:
GetPathOfProperty(() => Foo.Bar.Baz.SomeProperty );
这将 return 一个包含 "Foo.Bar.Baz.SomeProperty"