完全限定的属性名称 [英] Fully-qualified property name

查看:46
本文介绍了完全限定的属性名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试防止 System.NullReferenceException.

I'm trying to prevent System.NullReferenceException.

我有一个公司,里面有员工的集合.每个员工都有一组技能.

I have a Company, which has a collection of Employees. Each Employee has a collection of Skills.

SelectedEmployee 指向 Employee 集合中当前选定的元素.

SelectedEmployee points to the currently selected element within the Employee collection.

SelectedSkill 指向技能集合中当前选定的元素.

SelectedSkill points to the currently selected element within the collection of Skills.

我有一个 ListView,它的 ItemSource 绑定到 Skills 集合;ListView 的 SelectedItem 绑定到 SelectedSkill.

I have a ListView that has its ItemSource bound to the Skills collection; The ListView's SelectedItem is bound to the SelectedSkill.

删除技能时,我希望 ListView 滚动到最后一个元素.

When a Skill is deleted I want the ListView to scroll to the last element.

private void DeleteSelectedSkillFromSelectedEmployee()
{
    Company.SelectedEmployee.Skills.Remove(Company.SelectedEmployee.SelectedSkill);
    EmployeeSkillsListView.ScrollIntoView(Company.SelectedEmployee.Skills.Last());
}

如果尚未选择 Employee,则 SelectedEmployee 将为空.在方法内部执行任何操作时,这将导致 System.NullReferenceException.

If an Employee has not been selected, then SelectedEmployee will be null. This will cause a System.NullReferenceException when doing anything inside the method.

注意:我使用了一个扩展方法来替换 .Last() 所以它不会在空集合上出错.

NOTE: I've used an extension method to replace .Last() so it doesn't error on an empty collection.

为了解决这个问题,我使用了 Util 方法:

To get around this I use a Util method:

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());
    }
}

以上一切正常.这不是确切的场景或代码,所以不要担心更正上面的任何内容(假设它工作正常).这只是下面的问题,我真的很想知道.

Everything above works fine. It's not the exact scenario, or code, so don't worry about correcting anything above (just assume it works fine). It's just the question below I'm really interested in finding out.

(假设 SelectedEmployee 和 SelectedSkill 不为空)

(Imagine for this that SelectedEmployee and SelectedSkill are not null)

有没有办法获得属性的完全限定名称?所以我可以做这样的事情:

Is there any way of getting the fully qualified name of a property? So I could do something like:

if(Utils.PropertyExists(Company, GetFullyQualifiedName(Company.SelectedEmployee.SelectedSkill)))

其中 GetFullyQualifiedName(Object) 返回Company.SelectedEmployee.SelectedSkill".

Where GetFullyQualifiedName(Object) returns "Company.SelectedEmployee.SelectedSkill".

问题的第二部分:假设 SelectedEmployee 为 null:有没有办法允许将 NullReference 传递给方法?我 99.9% 确定答案是否定的 :)

Second part of the question: Imagine that SelectedEmployee is null: Is there any way of allowing a NullReference to be passed to a method? I'm 99.9% sure the answer is no :)

推荐答案

我不明白.为什么不只是:

I don't get it. Why not just:

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):


If you still want to have that GetFullyQualifiedName method, the nearest you could use could be something like (doesn't check for errors and it's just a quick 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 );

这将返回一个包含 "Foo.Bar.Baz.SomeProperty"

在小提琴中检查

这篇关于完全限定的属性名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆