任何方式,以避免在C#中物业内联优化? [英] Any way to avoid Property inline optimization in C#?

查看:185
本文介绍了任何方式,以避免在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 以这种方式工作,如做一些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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆