问题:
在Xamarin PCL项目中,对于不公开的属性,有没有办法验证具有给定名称的属性是否存在?
上下文:
在我的ViewModelBase
类中,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
只找到公共属性,即。即为私有属性调用OnPropertyChanged
会触发该异常。
我想削弱条件,以便为非公共属性调用OnPropertyChanged
只触发Debug.Print
,因为我的ViewModelBase.OnPropertyChanged
包含更多代码,因此调用OnPropertyChanged
可以对私人或受保护的财产有益。
但System.Type
获得的GetType()
对象和System.Reflection.TypeInfo
获得的GetType().GetTypeInfo()
对象in this SO answer似乎都没有找到除公共属性。
答案 0 :(得分:1)
实际答案,按照Furkan Fidan's comment:
GetRuntimeProperty
仅查找公共属性,因此如果给定属性不公开,则返回null
。
但是,您可以通过调用GetRuntimeProperties
方法检索所有属性的列表(包括非公开属性)。然后,您可以使用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
的评论:
此方法返回在指定类型上定义的所有属性,包括继承,非公共,实例和静态属性。
答案 1 :(得分:0)
您可以通过将非公开binding flag传递给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()不返回私有属性。