当前位置:  开发笔记 > 编程语言 > 正文

有什么方法可以避免C#中的Property内联优化?

如何解决《有什么方法可以避免C#中的Property内联优化?》经验,为你挑选了1个好方法。

所以我有一个旨在实现INotifyPropertyChanged的PropertyBag类.为了使这段代码尽可能干净地工作并避免用户错误,我使用堆栈来获取属性名称.请参阅,如果属性名称与实际属性完全不匹配,那么您将失败并且我正在尝试保护它.

所以,这是该类的示例用法:

public class MyData : PropertyBag
{
    public MyData()
    {
        Foo = -1;
    }

    public int Foo
    {
        get { return GetProperty(); }
        set { SetProperty(value); }
    }
}

基本PropertyBag的重要代码在这里:

public abstract class PropertyBag : INotifyPropertyChanged
{
    protected T GetProperty()
    {
        string propertyName = PropertyName((new StackTrace()).GetFrame(1));
        if (propertyName == null)
            throw new ArgumentException("GetProperty must be called from a property");

        return GetValue(propertyName);
    }

    protected void SetProperty(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"setter似乎正在优化为内联为SetProperty(-1).不幸的是,这个内联优化失败了我的SetProperty方法,因为我不再从属性调用它!失败.看来我不能以这种方式依赖StackTrace.

任何人都可以答:找出更好的方法来做到这一点,但仍然避免将"Foo"传递给GetProperty和SetProperty?
B:想办法告诉编译器在这种情况下不优化?



1> Marc Gravell..:

在这里使用堆栈是缓慢且不必要的; 我只想使用:

get { return GetProperty("Foo"); }
set { SetProperty("Foo", value); }

(提示:我已经使用自定义属性模型做了很多工作;我知道这很有效......)

另一个替代方法是对象键(使用引用相等来比较) - 很多ComponentModel方法都是这样工作的,WF/WPF中的一些属性也是如此:

static readonly object FooKey = new object();
...
get { return GetProperty(FooKey); }
set { SetProperty(FooKey, value); }

当然,您可以声明键的类型(带有Name属性),并使用:

static readonly PropertyKey FooKey = new PropertyKey("Foo");

等等; 然而,要回答这个问题:用它标记它(但要这样做):

[MethodImpl(MethodImplOptions.NoInlining)]

要么

[MethodImpl(MethodImplOptions.NoOptimization)]

要么

[MethodImpl(MethodImplAttributes.NoOptimization
    | MethodImplAttributes.NoInlining)]

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有