【问题标题】:CS0120 error under vs2010 beta 2 - object reference is requiredvs2010 beta 2 下的 CS0120 错误 - 需要对象引用
【发布时间】:2010-01-25 18:14:32
【问题描述】:

以下代码在vs2008下可以正常工作:

namespace N2.Engine.Globalization
{
    public class DictionaryScope : Scope
    {
                object previousValue;
        public DictionaryScope(IDictionary dictionary, object key, object value)
            : base(delegate
            {

                if (dictionary.Contains(key))
                    previousValue = dictionary[key];
                dictionary[key] = value;
            }, delegate
            {
                if (previousValue == null)
                    dictionary.Remove(key);
                else
                    dictionary[key] = previousValue;
            })
        {

        }
    }
}

但现在它报告非静态字段、方法或属性“N2.Engine.Globalization.DictionaryScope.previousValue”需要对象引用

编译器似乎发生了一些变化?任何解决方法?

更新:

关于使用虚拟方法的建议。这可能也行得通,因为虚拟方法将从基本构造函数中调用,我相信这也是不可能的?

这里是Scope(基类)的实现:

public class Scope: IDisposable
    {
        Action end;

        public Scope(Action begin, Action end)
        {
            begin();
            this.end = end;
        }

        public void End()
        {
            end();
        }

        #region IDisposable Members

        void IDisposable.Dispose()
        {
            End();
        }

        #endregion

【问题讨论】:

  • 这也不应该在 C# 2 中编译。 stackoverflow.com/questions/1600662/this-null-in-c
  • 确实,不建议从 ctor 调用虚拟方法,尽管我相信它可以编译(但可能......很麻烦)。我提到的虚拟方法是为了调用ctor的outside..
  • 嗯,您能详细解释一下第二种解决方法吗?不知道我很明白...

标签: c# visual-studio-2010


【解决方案1】:

更新:

§ 7.5.7 此访问权限

一个this-access由保留字this组成。

这个访问:

this

this-access 只允许在实例构造函数、实例方法或实例访问器的 block 中。

这些都不是。 4.0 编译器看起来是正确的。大概它并不高兴,因为这个本质上在类型未初始化时提供了对this 的访问。也许;-p

请注意,我预计并不是真正的 this.someField 导致了这种情况 - 更多的是字段的 使用 导致 this捕获,这意味着它想将this 实例提升到编译器生成的类上——就像你写的一样:

public MyCtor() : base( new SomeType(this).SomeMethod ) {...}

C# 3.0 编译器发现了上述对this 的滥用。


转载。调查。解决构造函数链接中的隐式 this 似乎是一个问题。

最可能的解决方法是使用virtual 方法而不是委托,并在派生类中简单地覆盖它。

一种解决方法是将实例作为参数传递,因此委托变为“obj => obj.whatever...”,并使用theDelegate(this);

更简单的复制:

public class MyBase {
    public MyBase(Action a) { }
}
public class MySub : MyBase {
    private string foo;
    // with "this.", says invalid use of "this"
    // without "this.", says instance required
    public MySub() : base(delegate { this.foo = "abc"; }) { }
}

我需要检查规范,但我不确定this 是否在这种情况下有效...所以 4.0 编译器可能是正确的。

【讨论】:

  • 你的分析是正确的。我们在 C# 3 周期的后期发现了这个错误,并将其推迟到 C# 4 进行修复。正如您正确指出的那样,在此上下文中允许匿名函数为在对象完成足够的初始化序列之前访问“this”提供了许多机会注意安全。正如 SLaks 在另一篇文章中指出的那样,无论如何,对于其中一些情况,我们并没有让代码生成“正确”。 (我在引号中说“正确”,因为当然没有为错误的程序定义正确的代码生成。)
  • 感谢您提供非常详尽的答复!我必须仔细阅读代码,看看它在哪里使用以及如何修复它。可能在很多地方(来自 N2 开源 CMS)
【解决方案2】:

添加: 静态对象previousValue;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2019-06-22
    相关资源
    最近更新 更多