任何方式,以避免在C#中物业内联优化? [英] Any way to avoid Property inline optimization in C#?
问题描述
所以我有一个旨在实现INotifyPropertyChanged一类的PropertyBag。为了使此代码的工作尽可能干净,避免用户错误,我使用栈来获得属性名。你看,如果属性名称不实际的属性完全匹配,那么你将有一个失败,我试图从保护。
So I have a PropertyBag class that is intended to implement INotifyPropertyChanged. In order to make this code work as cleanly as possible and to avoid user error, I am using the stack to get the property name. See, if the property name doesn't match the actual property exactly, then you will have a failure and I am trying to protect from that.
所以,这里是一个类的实例:
So, here is an example usage of the class:
public class MyData : PropertyBag
{
public MyData()
{
Foo = -1;
}
public int Foo
{
get { return GetProperty<int>(); }
set { SetProperty(value); }
}
}
为基数PropertyBag中最重要的代码是在这里:
The important code for the base PropertyBag is here:
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的构造富二传手似乎得到优化,内联为的SetProperty(-1)。不幸的是,内联优化失败出我的SetProperty方法,因为我不再从属性调用它!失败。 。看来,我不能这样依靠堆栈跟踪
So now that you have seen my code, I can tell you the problem... In some cases under release build, the "Foo" setter in the "MyData" constructor appears to be getting optimized to inline as SetProperty(-1). Unfortunately, this inline optimization fails out my SetProperty method because I am no longer calling it from a property! FAIL. It appears that I cannot rely on the StackTrace in this way.
任何人都可以
答:找出更好的方法来做到这一点,但仍然避免传递富?来的getProperty和setProperty
?b:找出一种方法来告诉编译器不要在这种情况下,优化
Can anyone
A: Figure out a better way to do this but still avoid passing in "Foo" to GetProperty and SetProperty?
B: Figure out a way to tell the compiler to not optimize in this case?
推荐答案
在这里使用堆栈是缓慢的和不必要的;我会简单地使用:
Using the stack here is slow and unnecessary; I would simply use:
get { return GetProperty<int>("Foo"); }
set { SetProperty("Foo", value); }
(提示:我已经做了很多工作,与自定义属性的模型;我知道,这效果很好...)
(hint: I've done a lot of work with custom property models; I know that this works well...)
另一种选择是一个对象键(使用引用相等比较) - 很多 ComponentModel $ C $的C>以这种方式工作,如做一些WF / WPF的属性:
Another alternative is an object key (use reference equality to compare) - a lot of ComponentModel
works this way, as do some of the properties in WF/WPF:
static readonly object FooKey = new object();
...
get { return GetProperty<int>(FooKey); }
set { SetProperty(FooKey, value); }
当然,你可以声明为密钥的类型(以名称
属性),并使用:
static readonly PropertyKey FooKey = new PropertyKey("Foo");
等;然而,要回答这个问题:标记(但不要做到这一点),用:
[MethodImpl(MethodImplOptions.NoInlining)]
或
[MethodImpl(MethodImplOptions.NoOptimization)]
< S>或
[MethodImpl(MethodImplAttributes.NoOptimization
| MethodImplAttributes.NoInlining)]
这篇关于任何方式,以避免在C#中物业内联优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!