调用基本构造函数时如何使用'this'关键字

时间:2019-10-01 14:53:00

标签: c#

abstract class Foo 
{
    private readonly FooAttributeCollection attributes;

    public Foo(FooAttributeCollection attributes) 
    {
        this.attributes = attributes;
    }
}

class FooAttributeCollection 
{
    public FooAttributeCollection(Foo owner) 
    {
    }
}

class Bar : Foo 
{
    public Bar() : base(new FooAttributeCollection(this)) 
    {
    }
}

假设我必须编写类似上面的代码。并且无法修改类FooFooAttributeCollection

当我这样写Bar类时,出现以下错误:

  

'this'关键字不能在这种情况下使用。

出现在base(...)

行附近

有什么好主意要解决吗?

5 个答案:

答案 0 :(得分:2)

如果无法修改 Foo FooAttributeCollection ,则此代码似乎是一个错误的设计。 要实例化派生的Foo类,必须先实例化FooAttributeCollection,并且要实例化FooAttributeCollection,必须实例化相同的派生Foo类。 没有“作弊”就无法解决的无限循环依赖

也许可以通过复制(如Uwe Keim所说)或使用真实的代理/动态代理创建DerivedClass代理来解决此问题。

答案 1 :(得分:1)

你不能写:

public Bar() : base(new FooAttributeCollection(this)) 

因为this(当前对象)必须放在方法的实现中,而不是方法签名中:因此,您无权访问该对象的当前实例。

您不能在每个方法声明中都做这样的事情,因为您不在实现范围内,而在类型定义范围内,即在类的“接口”中,即其定义。

使用带有basethis关键字的调用基或边构造函数是一种特殊的语言构造,用于传递不是类本身实例的参数。

您可以使用@Tohm解决方案来解决您的目标。

答案 2 :(得分:1)

为什么不影响抽象类中的属性?如果要在FooAttributeCollection中使用,可以在Bar类中强制转换所有者。

abstract class Foo 
{
    private readonly FooAttributeCollection attributes;

    public Foo(FooAttributeCollection attributes=null) 
    {
        if(attributes = null) {attributes = new FooAttributeCollection(this);}
        this.attributes = attributes;
    }
}

class FooAttributeCollection 
{
    public FooAttributeCollection(Foo owner) 
    {
        var ownerInBar = owner as Bar;

    }
}

class Bar : Foo 
{
    public Bar() : base() 
    {
    }
}

答案 3 :(得分:0)

需要构造类之后才能访问this关键字。

您可以尝试以下风声。

class Bar : Foo
    {
        private readonly FooAttributeCollection attributes;
        public Bar() : base(null)
        {
            var attributes = new FooAttributeCollection(this);
        }
    }

答案 4 :(得分:0)

尝试这种方式:

public class Bar : Foo
    {
        public Bar(FooAttributeCollection attributes) : base(attributes)
        {
        }
    }

其他示例:

public class BaseClass
    {
        int num;
        public BaseClass(int i)
        {
            num = i;
            Console.WriteLine("in BaseClass(int i)");
        }
    }
public class DerivedClass : BaseClass
    {         
        // This constructor will call BaseClass.BaseClass(int i)
        public DerivedClass(int i) : base(i)
        {
        }
    }