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))
{
}
}
假设我必须编写类似上面的代码。并且无法修改类Foo
和FooAttributeCollection
。
当我这样写Bar
类时,出现以下错误:
'this'关键字不能在这种情况下使用。
出现在base(...)
有什么好主意要解决吗?
答案 0 :(得分:2)
如果无法修改 Foo 和 FooAttributeCollection ,则此代码似乎是一个错误的设计。 要实例化派生的Foo类,必须先实例化FooAttributeCollection,并且要实例化FooAttributeCollection,必须实例化相同的派生Foo类。 没有“作弊”就无法解决的无限循环依赖
也许可以通过复制(如Uwe Keim所说)或使用真实的代理/动态代理创建DerivedClass代理来解决此问题。
答案 1 :(得分:1)
你不能写:
public Bar() : base(new FooAttributeCollection(this))
因为this
(当前对象)必须放在方法的实现中,而不是方法签名中:因此,您无权访问该对象的当前实例。
您不能在每个方法声明中都做这样的事情,因为您不在实现范围内,而在类型定义范围内,即在类的“接口”中,即其定义。
使用带有base
或this
关键字的调用基或边构造函数是一种特殊的语言构造,用于传递不是类本身实例的参数。
您可以使用@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)
{
}
}