在 Xamarin PCL 中按名称验证非 public 属性 是否存在
Verify existence of non-public property by name in Xamarin PCL
问题:
在 Xamarin PCL 项目中,对于 不是 属性 的 属性 是否存在任何方法来验证是否存在具有给定名称的 属性 =47=] public?
上下文:
在我的 ViewModelBase
class 中,OnPropertyChanged
调用了一个仅调试方法。它帮助我找到 OnPropertyChanged 的错误参数,以防我无法使用 CallerMemberName
逻辑并且必须为 propertyName
:
传递一个显式值
public abstract class ViewModelBase : INotifyPropertyChanged
{
// ...
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
VerifyPropertyName(propertyName);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// More code that is the reason why calling OnPropertyChanged can
// make sense even for private or protected properties in my code.
}
[Conditional("DEBUG"), DebuggerStepThrough]
private void VerifyPropertyName(string propertyName)
{
// This only finds public properties
if (GetType().GetRuntimeProperty(propertyName) == null) {
// TODO
// Check if there is a non-public property
// If there is, only print a hint
throw new ArgumentException("Invalid property name: " + propertyName);
}
}
// ...
}
问题是 GetRuntimeProperty
只找到 public 属性,i。 e.为私有 属性 调用 OnPropertyChanged
会触发该异常。
我想弱化条件,以便为非 public 属性调用 OnPropertyChanged
只会触发 Debug.Print
,因为我的 ViewModelBase.OnPropertyChanged
包含更多代码,因此调用 OnPropertyChanged
可以 对私有或受保护的财产有益。
但是 GetType()
获得的 System.Type
对象和 GetType().GetTypeInfo()
获得的 System.Reflection.TypeInfo
对象都没有,如前所述 in this SO answer 似乎没有找到其他东西的方法public 属性。
可以通过非publicbinding flag to GetFields方法获取类型的私有字段。请参阅下面的快速示例。
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
编辑:
有关详细信息,请参阅评论,但基本上要实现@LWChris 的要求,您需要在 GetType() 上调用 GetRuntimeProperties(),因为 GetRuntimeProperty() 没有 return 私有属性。
实际答案,根据 :
GetRuntimeProperty
只找到 public 属性,所以它 returns null
如果给定的 属性 不是 public.
但是您可以通过调用 GetRuntimeProperties
方法检索所有属性(包括 non-public 属性)的列表。然后,您可以使用 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
的备注:
This method returns all properties defined on the specified type, including inherited, non-public, instance, and static properties.
问题:
在 Xamarin PCL 项目中,对于 不是 属性 的 属性 是否存在任何方法来验证是否存在具有给定名称的 属性 =47=] public?
上下文:
在我的 ViewModelBase
class 中,OnPropertyChanged
调用了一个仅调试方法。它帮助我找到 OnPropertyChanged 的错误参数,以防我无法使用 CallerMemberName
逻辑并且必须为 propertyName
:
public abstract class ViewModelBase : INotifyPropertyChanged
{
// ...
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
VerifyPropertyName(propertyName);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// More code that is the reason why calling OnPropertyChanged can
// make sense even for private or protected properties in my code.
}
[Conditional("DEBUG"), DebuggerStepThrough]
private void VerifyPropertyName(string propertyName)
{
// This only finds public properties
if (GetType().GetRuntimeProperty(propertyName) == null) {
// TODO
// Check if there is a non-public property
// If there is, only print a hint
throw new ArgumentException("Invalid property name: " + propertyName);
}
}
// ...
}
问题是 GetRuntimeProperty
只找到 public 属性,i。 e.为私有 属性 调用 OnPropertyChanged
会触发该异常。
我想弱化条件,以便为非 public 属性调用 OnPropertyChanged
只会触发 Debug.Print
,因为我的 ViewModelBase.OnPropertyChanged
包含更多代码,因此调用 OnPropertyChanged
可以 对私有或受保护的财产有益。
但是 GetType()
获得的 System.Type
对象和 GetType().GetTypeInfo()
获得的 System.Reflection.TypeInfo
对象都没有,如前所述 in this SO answer 似乎没有找到其他东西的方法public 属性。
可以通过非publicbinding flag to GetFields方法获取类型的私有字段。请参阅下面的快速示例。
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
编辑:
有关详细信息,请参阅评论,但基本上要实现@LWChris 的要求,您需要在 GetType() 上调用 GetRuntimeProperties(),因为 GetRuntimeProperty() 没有 return 私有属性。
实际答案,根据
GetRuntimeProperty
只找到 public 属性,所以它 returns null
如果给定的 属性 不是 public.
但是您可以通过调用 GetRuntimeProperties
方法检索所有属性(包括 non-public 属性)的列表。然后,您可以使用 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
的备注:
This method returns all properties defined on the specified type, including inherited, non-public, instance, and static properties.