考虑这个伪造的例子...
public abstract class CollectionItem<TSelf> {
protected CollectionItem(ICollection<TSelf> siblings)
=> Siblings = siblings;
public ICollection<TSelf> Siblings { get; }
}
public class Foo : CollectionItem<Foo>{
public Foo()
: base(new FooCollection){}
}
public class FooCollection : ObservableCollection<Foo>{
}
使用上述方法,Foo
现在具有Siblings
属性。但是,这有三个问题。
Foo
Siblings
本身的类型不是实际的集合类型,而是接口。Siblings
集合的实例解决#2和#3,我做了这个更改...
public class CollectionItem<TSelf, TSiblings>
where TSiblings : ICollection<TSelf>, new() {
protected CollectionItem()
=> Siblings = new TSiblings();
public TSiblings Siblings { get; }
}
但是我仍然必须传递看似多余的Foo
作为第一个类型参数,像这样...
public class Foo : CollectionItem<Foo, FooCollection>{
}
在Swift中,您有一个隐含的Self
数据类型,该数据类型始终表示当前实例的类型,这意味着如果在基类中使用Self
,则它实际上是该数据类型的替代者子类的。如果愿意,可以将其视为隐式泛型。
在C#中具有该功能可以让我做这样的事情...
public class CollectionItem<TSiblings>
where TSiblings : ICollection<Self>, new() { // Note it uses 'Self' here
protected CollectionItem()
=> Siblings = new TSiblings();
public TSiblings Siblings { get; }
}
public class Foo : CollectionItem<FooCollection>{
}
public class Laa : CollectionItem<LaaCollection>{
}
在上面,对于Foo
的实例,Self
指的是Foo
。对于Laa
的实例,Self
是指Laa
。无需传递冗余类型参数。
那么C#有什么类似的东西吗?