C# 按名称验证Xamarin PCL中是否存在非公共属性

C# 按名称验证Xamarin PCL中是否存在非公共属性,c#,xamarin,system.reflection,C#,Xamarin,System.reflection,问题: 在Xamarin PCL项目中,对于非公共属性,是否有任何方法可以验证具有给定名称的属性是否存在 背景: 在我的ViewModelBase类中,OnPropertyChanged调用一个仅调试的方法。如果我无法使用CallerMemberName逻辑并且必须为propertyName传递显式值,它可以帮助我找到OnPropertyChanged的错误参数: 问题是GetRuntimeProperty只查找公共属性,即。E为私有属性调用OnPropertyChanged会触发该异常 我想削

问题:

在Xamarin PCL项目中,对于非公共属性,是否有任何方法可以验证具有给定名称的属性是否存在

背景:

在我的ViewModelBase类中,OnPropertyChanged调用一个仅调试的方法。如果我无法使用CallerMemberName逻辑并且必须为propertyName传递显式值,它可以帮助我找到OnPropertyChanged的错误参数:

问题是GetRuntimeProperty只查找公共属性,即。E为私有属性调用OnPropertyChanged会触发该异常

我想削弱这种条件,以便对非公共属性调用OnPropertyChanged只会触发Debug.Print,因为我的ViewModelBase.OnPropertyChanged包含更多代码,因此调用OnPropertyChanged对私有或受保护的属性可能会有好处


但是,通过GetType获得的System.Type对象和通过GetType.GetTypeInfo获得的System.Reflection.TypeInfo(如上所述)似乎都没有找到除公共属性以外的任何其他属性的方法。

通过将非公共方法传递给方法,可以获得类型的私有字段。请参见下面一个快速而肮脏的示例

using System;
using System.Reflection;

class MyClass
{
    private int privField;

    public MyClass(int val)
    {
        this.privField = val;
    }

    public void printValueOfPrivate()
    {
        var fields = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
        Console.WriteLine("Name: " + fields[0].Name + " Value: " + fields[0].GetValue(this));
    }
}

public class HelloWorld
{
    static public void Main()
    {
        var mc = new MyClass(7);
        mc.printValueOfPrivate();
    }
}
输出:

Name: privField Value: 7
编辑:

有关详细信息,请参阅注释,但基本上要实现@lwcris所希望的,您需要在GetType上调用GetRuntimeProperties,因为GetRuntimeProperty不返回私有属性。

实际答案如下:

只查找公共属性,因此如果给定属性不是公共属性,则返回null

但是,您可以通过调用该方法来检索包括非公共属性在内的所有属性的列表。然后可以使用LINQ过滤结果

private void VerifyPropertyName(string propertyName)
{
  if (GetType().GetRuntimeProperty(propertyName) != null) {
    // The property is public
  } else if (GetType().GetRuntimeProperties().Any(p => p.Name == propertyName)) {
    // The property is not public, but it exists
  } else {
    // The property does not exist
  }
}
另请参见GetRuntimeProperties的备注:

此方法返回指定类型上定义的所有属性,包括继承属性、非公共属性、实例属性和静态属性


对不起,我的错-我只在MacOS上尝试过mono。再深入一点看,您是对的,PCL不支持GetFields,但需要使用GetRuntimeFields和GetRuntimeProperties。也应包括非私人的意见。您正在查看的文档是什么?文档是,当我运行使用if GetType.GetRuntimePropertypropertyName==null throw….的代码时,我遇到一个异常,并且GetType.GetTypeInfo.GetDeclaredPropertystring propertyName有一个文档返回一个表示由GetRuntimeProperty的当前类型。文档没有说明它检索非公共字段的任何内容。我知道这可能效率不高,但为了科学起见,你能试着调用GetRuntimeProperties并枚举它们,看看你要找的属性是否存在吗?哈,你说得对!GetType.GetRuntimePropertypropertyName返回null,但GetType.GetRuntimeProperties返回实际包含属性元素的数组。编辑您的答案以包含此信息,我将接受它。
private void VerifyPropertyName(string propertyName)
{
  if (GetType().GetRuntimeProperty(propertyName) != null) {
    // The property is public
  } else if (GetType().GetRuntimeProperties().Any(p => p.Name == propertyName)) {
    // The property is not public, but it exists
  } else {
    // The property does not exist
  }
}