所以我有一个旨在实现 INotifyPropertyChanged 的 PropertyBag 类。为了使此代码尽可能干净地工作并避免用户错误,我使用堆栈来获取属性名称。看,如果属性名称与实际属性不完全匹配,那么您将失败,我正在努力避免这种情况。
因此,这是该类的示例用法:
public class MyData : PropertyBag
{
public MyData()
{
Foo = -1;
}
public int Foo
{
get { return GetProperty<int>(); }
set { SetProperty(value); }
}
}
基本 PropertyBag 的重要代码在这里:
public abstract class PropertyBag : INotifyPropertyChanged
{
protected T GetProperty<T>()
{
string propertyName = PropertyName((new StackTrace()).GetFrame(1));
if (propertyName == null)
throw new ArgumentException("GetProperty must be called from a property");
return GetValue<T>(propertyName);
}
protected void SetProperty<T>(T value)
{
string propertyName = PropertyName((new StackTrace()).GetFrame(1));
if (propertyName == null)
throw new ArgumentException("SetProperty must be called from a property");
SetValue(propertyName, value);
}
private static string PropertyName(StackFrame frame)
{
if (frame == null) return null;
if (!frame.GetMethod().Name.StartsWith("get_") &&
!frame.GetMethod().Name.StartsWith("set_"))
return null;
return frame.GetMethod().Name.Substring(4);
}
}
所以现在你已经看到了我的代码,我可以告诉你问题......在某些情况下,在发布版本下,“MyData”构造函数中的“Foo”设置器似乎被优化为内联为 SetProperty(-1)。不幸的是,这种内联优化使我的 SetProperty 方法失败,因为我不再从属性中调用它!失败。看来我不能以这种方式依赖 StackTrace。
任何人都可以 A:找出更好的方法来做到这一点,但仍然避免将“Foo”传递给 GetProperty 和 SetProperty?
B:想办法告诉编译器在这种情况下不要优化?