简体   繁体   English

完全限定的财产名称

[英]Fully-qualified property name

I'm trying to prevent System.NullReferenceException. 我正在尝试防止System.NullReferenceException。

I have a Company, which has a collection of Employees. 我有一家公司,该公司有一组员工。 Each Employee has a collection of Skills. 每个员工都有一套技能。

SelectedEmployee points to the currently selected element within the Employee collection. SelectedEmployee指向Employee集合中当前选定的元素。

SelectedSkill points to the currently selected element within the collection of Skills. SelectedSkill指向技能集合中当前选定的元素。

I have a ListView that has its ItemSource bound to the Skills collection; 我有一个ListView,它的ItemSource绑定到Skills集合; The ListView's SelectedItem is bound to the SelectedSkill. ListView的SelectedItem绑定到SelectedSkill。

When a Skill is deleted I want the ListView to scroll to the last element. 删除技能后,我希望ListView滚动到最后一个元素。

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

If an Employee has not been selected, then SelectedEmployee will be null. 如果尚未选择Employee,则SelectedEmployee将为null。 This will cause a System.NullReferenceException when doing anything inside the method. 在方法内部执行任何操作时,这将导致System.NullReferenceException。

NOTE: I've used an extension method to replace .Last() so it doesn't error on an empty collection. 注意:我使用了扩展方法来替换.Last(),因此它在空集合上不会出错。

To get around this I use a Util method: 为了解决这个问题,我使用了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;
    }
}

So it now looks like this: 所以现在看起来像这样:

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. 这只是我真正有兴趣找出的以下问题。

(Imagine for this that SelectedEmployee and SelectedSkill are not null) (为此可以想象,SelectedEmployee和SelectedSkill不为空)

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

Where GetFullyQualifiedName(Object) returns "Company.SelectedEmployee.SelectedSkill". 其中GetFullyQualifiedName(Object)返回“ Company.SelectedEmployee.SelectedSkill”。

Second part of the question: Imagine that SelectedEmployee is null: Is there any way of allowing a NullReference to be passed to a method? 问题的第二部分:假设SelectedEmployee为null:是否有任何方法可以将NullReference传递给方法? I'm 99.9% sure the answer is no :) 我99.9%确信答案是否定的:)

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

Or in C#6 或在C#6中

if(Company?.SelectedEmployee?.Skills != null) 
{
  ...
}

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): 如果您仍然希望拥有该GetFullyQualifiedName方法,则可以使用的最接近的方法可能是(不检查错误,这只是一个快速的技巧):

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

Then use it like: 然后像这样使用它:

GetPathOfProperty(() => Foo.Bar.Baz.SomeProperty );

This would return a string containing "Foo.Bar.Baz.SomeProperty" 这将返回包含"Foo.Bar.Baz.SomeProperty"的字符串

Check it in a Fiddle 在小提琴中检查

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 获取OU的标准名称 - Get fully-qualified name of an OU 在Roslyn中获取完全限定的元数据名称 - Get fully-qualified metadata name in Roslyn C#:为什么使用时仍需要完全限定的名称? - C#: why is fully-qualified name needed despite using? 名为程序集名称的标准名称空间是什么? - What is the fully-qualified namespace with the assembly name called? 如何即时返回方法的完全限定名称? - How to return a method's fully-qualified name on the fly? 如何创建表达式 <Action> 在.NET中给出了完全合格的类名和方法名? - How do I create an Expression<Action> given a fully-qualified class name and a method name in .NET? 如果我只有类名和dll名称,如何获得完全限定的程序集引用? - How do I get a fully-qualified assembly reference if I only have the class name and dll name? 使用反射嵌套的完全限定属性名称 - Nested fully qualified property name using reflection 从完全限定的类名生成“using”指令,而不必转到Visual Studio 2017中的代码文件的顶部 - Generate “using” directive from fully-qualified class name without having to go to the top of the code file in Visual Studio 2017 使用using语句将代码转换为标准名称 - Convert code with using statements to fully-qualified names
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM